[BONUS]
doseq
dotimes
클로저에서는, 모든 자료구조를 시퀀스로 말할 수 있습니다. 앞서,
벡터
와맵
이 전부 시퀀스라고 배웠습니다. 문자열도 역시 시퀀스이며, seq로 다룰 수 있는 것들은 전부 시퀀스입니다.
first
함수 반환 유무 seq로 다룰 수 있는 것이라면, 시퀀스의 첫 번째 아이템을 반환합니다.
first
함수를 통해서 말이죠. 시퀀스인지 아닌지 테스트할 때 쓸만합니다.
first
의 결과(turtle-names)
;=> [:trinity :neo :oracle :cypher] ; vector
(first (turtle-names))
;=> :trinity ; the first item
(:trinity (state))
;=> {:x 0, :y 0, :angle 90, :color [30 30 30]} ; map
(first (:trinity (state)))
[:x 0] ; the first item
(first "Hello, World!") ; string
;=> \H ; the first item
(first :trinity) ; keyword is not seq-able
;=> IllegalArgumentException Don't know how to create ISeq from:
clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:528)
클로저는 시퀀스의 요소들을 반복해서 처리하는 데에 아주 능합니다. 시퀀스를 다루는 많은 함수들이 있습니다. 예를 들어,
doseq
,dotimes
,for
,loop
,doall
,dorun
함수들이 있습니다.map
과reduce
함수를 이미 “함수를 인자로 갖는 함수” 섹션에서 보았습니다. 이것들 또한 시퀀스를 다루는 함수 입니다.
doseq
doseq
(do sequence)은 시퀀스를 다루는 함수들 중 잘 쓰이는 함수들 중 하나입니다.map
함수와 아주 비슷하게 기능합니다. 함수는 주어진 시퀀스에서 각 요소를 사용해, 본체 부분을 반복적으로 실행합니다.
doseq
함수는 첫번째 인자를 바인딩 벡터로 받습니다. 그 인자는 이상해 보이는 벡터일 수도 있습니다 :[name sequence]
의 형식입니다. 시퀀스의 각 요소가 반복하면서,name
에 할당됩니다.
;; doseq example
(doseq [n (turtle-names)] (forward n 40))
chord
함수 이상dotimes
dotimes
(do number of times) 함수는 시퀀스를 다루는 함수들 중 잘 쓰이는 또 다른 함수입니다.doseq
함수처럼 반복적으로 주어진 본체 부분을 실행합니다. 차이점은 인자를 받는 방법입니다.dotimes
의 첫번쨰 인자는[name max-integer]
형식입니다.
dotimes
함수는 다른 프로그래밍 언어에서 for 문과 가장 유사합니다. 이 함수는ntn
함수와 조합하면, 주어진 시퀀스에 대한 인덱스 접근이 가능합니다.
;; assuming there are multiple turtles
(def names (turtle-names))
(dotimes [n (count names)] (right (nth names n) (* 45 n)))