수색…
소개
트랜스 듀서는 컨텍스트와 독립적으로 데이터를 처리하기위한 구성 가능 구성 요소입니다. 따라서 입력 소스 나 출력 싱크에 대한 지식 없이도 콜렉션, 스트림, 채널 등을 처리하는 데 사용할 수 있습니다.
Clojure 코어 라이브러리는 1.7로 확장되어 시퀀스없이 호출 될 때 map, filter, take 등과 같은 시퀀스 함수가 변환기를 반환합니다. 트랜스 듀서는 특정 계약이있는 함수이기 때문에 일반 comp
함수를 사용하여 구성 할 수 있습니다.
비고
트랜스 듀서는 게으른 것을 소비 할 때 제어되도록합니다. 예를 들어 into
는 예상대로 열망하지만, sequence
는 트랜스 듀서를 통해 sequence
를 느리게 소비합니다. 그러나, 게으름 보장은 다릅니다. 처음에는 요소를 생성하기에 충분한 소스가 소비됩니다.
(take 0 (sequence (map #(do (prn '-> %) %)) (range 5)))
;; -> 0
;; => ()
또는 목록이 비어 있는지 결정하십시오.
(take 0 (sequence (comp (map #(do (prn '-> %) %)) (remove number?)) (range 5)))
;; -> 0
;; -> 1
;; -> 2
;; -> 3
;; -> 4
;; => ()
일반적인 게으른 시퀀스 동작과 다른 점은 다음과 같습니다.
(take 0 (map #(do (prn '-> %) %) (range 5)))
;; => ()
작은 변환기가 벡터에 적용됨
(let [xf (comp
(map inc)
(filter even?))]
(transduce xf + [1 2 3 4 5 6 7 8 9 10]))
;; => 30
이 예에서는 로컬 할당 진동자 생성 xf
하고 사용 transduce
일부 데이터에 적용. 변환기는 각 입력에 1을 더하고 짝수 만 반환합니다.
transduce
는 reduce
와 같으며 제공된 +
함수를 사용하여 입력 콜렉션을 단일 값으로 축소합니다.
이것은 thread-last 매크로와 같지만 입력 데이터를 계산과 분리합니다.
(->> [1 2 3 4 5 6 7 8 9 10]
(map inc)
(filter even?)
(reduce +))
;; => 30
트랜스 듀서 적용
(def xf (filter keyword?))
컬렉션에 적용하여 시퀀스를 반환합니다.
(sequence xf [:a 1 2 :b :c]) ;; => (:a :b :c)
컬렉션에 적용하여 결과 컬렉션을 다른 함수로 축소합니다.
(transduce xf str [:a 1 2 :b :c]) ;; => ":a:b:c"
컬렉션에 적용하고, conj
다른 모음으로 결과를 :
(into [] xf [:a 1 2 :b :c]) ;; => [:a :b :c]
변환기를 사용하여 메시지를 필터링하는 코어 비동기 채널을 만듭니다.
(require '[clojure.core.async :refer [chan >!! <!! poll!]])
(doseq [e [:a 1 2 :b :c]] (>!! ch e))
(<!! ch) ;; => :a
(<!! ch) ;; => :b
(<!! ch) ;; => :c
(poll! ch) ;;=> nil
트랜스 듀서 생성 / 사용
따라서 Clojure 맵과 필터에서 가장 많이 사용되는 함수는 콜렉션과 함께 호출되지 않으면 트랜스 듀서 (변환 가능한 알고리즘 변환)를 반환하도록 수정되었습니다. 그 의미는:
(map inc)
변환기를 반환하고 그래서 (filter odd?)
장점 : comp는 함수를 하나의 함수로 구성 할 수 있습니다. 즉, 컬렉션을 한 번만 탐색하는 것을 의미합니다. 일부 시나리오에서는 실행 시간을 50 % 이상 절약합니다.
정의:
(def composed-fn (comp (map inc) (filter odd?)))
용법:
;; So instead of doing this:
(->> [1 8 3 10 5]
(map inc)
(filter odd?))
;; Output [9 11]
;; We do this:
(into [] composed-fn [1 8 3 10 5])
;; Output: [9 11]