2013-09-22 66 views
7

Tôi muốn hiểu cách thức thành ngữ để hoạt động trên các bộ sưu tập có kích thước khác nhau trong clojure. Có cách nào tôi có thể cho biết chức năng 'bản đồ' để pad phần còn lại của một bộ sưu tập với một số giá trị mặc định?Sử dụng 'bản đồ' với các bộ sưu tập có kích thước khác nhau trong clojure

Như một ví dụ, giả sử tôi có 3 vectơ:

(def x [1 2 3 4]) 
(def y [1 2 3 4 5]) 
(def z [1 2 3 4 5 6 7]) 

(map + x y z) ; yields (3 6 9 12) 

Trong trường hợp này, làm thế nào tôi pad x và y với zero và có thể có năng suất này:

(3 6 9 12 10 6 7) 

Trả lời

10

map không tự làm, nhưng bạn có thể sử dụng kết hợp của concatrepeat để có được kết quả mong muốn:

(def x [1 2 3 4]) 
(def y [1 2 3 4 5]) 
(def z [1 2 3 4 5 6 7]) 

(map + 
    (concat x (repeat 0)) 
    (concat y (repeat 0)) 
    z) ; => (3 6 9 12 10 6 7) 

Đây là tài liệu API cho concat và cho repeat.

Và đây là một phác thảo về cách bạn có thể tóm tắt điều này một chút, vì vậy bạn không cần phải biết bộ sưu tập nào dài nhất. (Trong đoạn mã ở trên, nếu bạn concat tất cả các bộ sưu tập đến (repeat 0) bạn sẽ có một chuỗi vô hạn).

(defn map-longest 
    [f default & colls] 
    (lazy-seq 
    (when (some seq colls) 
    (cons 
     (apply f (map #(if (seq %) (first %) default) colls)) 
     (apply map-longest f default (map rest colls)))))) 

(map-longest + 
      0 
      [1 2 3 4] 
      [1 2 3 4 5] 
      [1 2 3 4 5 6 7]) ; => (3 6 9 12 10 6 7) 

Bạn có thể thấy một vài cách tiếp cận khác làm câu trả lời cho this previous question on Stack Overflow.

Các vấn đề liên quan