Reputation: 14162
I have two seqs h-keys
and h-values
. I need to build up a seq of all possible maps that assoc n
elements from h-keys
with elements from h-values
.
(def h-keys [:a :b :c])
(def h-values [1 2])
(def res (f h-keys h-values 2))
(= (set res) #{{:a 1, :b 1} {:a 1 :b 2} {:a 2 :b 1} {:a 2 :b 2} {:a 1, :c 1} {:a 1 :c 2} {:a 2 :c 1} {:a 2 :c 2} {:c 1, :b 1} {:c 1 :b 2} {:c 2 :b 1} {:c 2 :b 2}})
How would I go about writing f
?
Upvotes: 2
Views: 80
Reputation: 14162
(require '[clojure.math.combinatorics :as combo])
(defn f [keys values n]
(set (for [res-keys (combo/combinations keys n)
res-values (combo/selections values n)]
(zipmap res-keys res-values))))
Upvotes: 1
Reputation: 4702
Alternative implementation using combinatorics
(require '[clojure.math.combinatorics :as combo])
(defn f
[keys vals n]
(->> (combo/cartesian-product (combo/combinations keys n)
(combo/selections vals n))
(map (partial apply zipmap))
set))
> (f [:a :b :c] [1 2] 2)
=> #{{:c 2, :a 1} {:c 1, :a 1} {:c 2, :a 2} {:b 1, :a 1} {:c 1, :a 2} {:b 2, :a 1} {:c 2, :b 1} {:c 1, :b 1} {:c 2, :b 2} {:b 1, :a 2} {:c 1, :b 2} {:b 2, :a 2}}
Upvotes: 1
Reputation: 14162
(require '[clojure.math.combinatorics :as combo])
(defn f [keys values n]
(mapcat (fn [keys]
(map (fn [values]
(apply assoc {} (interleave keys values)))
(combo/selections values n)))
(combo/combinations keys n)))
Upvotes: 0