Reputation: 43
I think I am struggling with some basics of clojure's immutable hash map.
I want to turn a list of tuples in to a hash-map
([:a 2] [:b 3] [:a 1] [:b 3]) ==> {:a #{2 1}, :b #{3}}
That is, in python I would do:
hash_map = defaultdict(set)
for key, value in my_list:
hash_map[key].add(value)
How should I do this in clojure?
Upvotes: 0
Views: 141
Reputation: 13473
Slow but sure:
(defn pairs-to-graph [pairs]
(apply merge-with clojure.set/union
(map (fn [[k v]] {k #{v}}) pairs)))
(pairs-to-graph '([:a 2] [:b 3] [:a 1] [:b 3]))
;{:b #{3}, :a #{1 2}}
Upvotes: 0
Reputation: 6073
Oh, so many useful Clojure functions to touch:
(reduce
(fn [m [k v]]
(update-in m [k] (fnil conj #{}) v))
{} data)
;; => {:b #{3}, :a #{1 2}}
It's actually quite close to the Python code: you iterate over the seq using reduce
, add the value to the map using update-in
and conj
and make sure the value is initialized with an empty set using fnil
.
Upvotes: 2
Reputation: 10624
(defn pairs-to-hash [pairs]
(into {}
(map (fn [kv]
[(key kv) (->> kv val (map second) set)])
(group-by first pairs))))
(pairs-to-hash '([:a 2] [:b 3] [:a 1] [:b 3]))
This was a quick attempt that I think could be neatened up a bit.
Upvotes: 0