在Clojure中迭代所有对集合的惯用方法

Fra*_*ank 17 clojure sequence

给定一个集合,我想迭代集合中的所有对.例

(all-pairs seq)

(all-pairs '(a b c d)) => ([a b] [a c] [a d] [b c] [b d] [c d]))
Run Code Online (Sandbox Code Playgroud)

这是我的想法

(defn all-pairs [coll]
  (for [ [idx elmt] (indexed coll)
         other-elmt (subvec coll (inc idx))]
     (vector elmt other-elm)))
Run Code Online (Sandbox Code Playgroud)

但它并不像惯用语

小智 17

怎么样:

(use 'clojure.contrib.combinatorics)
(vec (map vec (combinations '(a b c d) 2)))
Run Code Online (Sandbox Code Playgroud)

  • 将clojure.contrib.combinatorics移至clojure.math.combinatorics:https://clojure.github.io/math.combinatorics/ (3认同)

小智 7

(defn all-pairs [coll]
  (loop [[x & xs] coll
         result []]
    (if (nil? xs)
      result
      (recur xs (concat result (map #(vector x %) xs))))))
Run Code Online (Sandbox Code Playgroud)


May*_*iel 6

懒惰,而且比较快.

(defn all-pairs [coll]
  (when-let [s (next coll)]
    (lazy-cat (for [y s] [(first coll) y])
              (all-pairs s))))
Run Code Online (Sandbox Code Playgroud)
(defn all-pairs [coll]
  (let [x (first coll) xs (next coll)]
    (when xs
      (lazy-cat
       (map (fn [y] [x y]) xs) 
       (all-pairs xs)))))
Run Code Online (Sandbox Code Playgroud)

(all-pairs [1 2 3 4]) ;; => ([1 2] [1 3] [1 4] [2 3] [2 4] [3 4])

(all-pairs '(a b c d)) ;; => ([a b] [a c] [a d] [b c] [b d] [c d])