Reputation: 4191
I've put together the function below. It's supposed to take in a nested (multi-tiered) map and return a sequence of flat maps; however, it currently returns a sequence within a sequence.
Does anyone know why the sequence is being nested within another sequence?
(defn collapse [data & keys-coll]
(if (map? data)
(for [[k v] data]
(collapse v (if (nil? keys-coll)
(conj [] k)
(conj (into [] keys-coll) k))))
(hash-map (flatten keys-coll) data)))
(collapse {"a" {2011 [["a" 2011 "dan"] ["a" 2011 "ari"]] 2010 [["a" 2010 "jon"]]}})
Results in:
( ({("a" 2011) [["a" 2011 "dan"] ["a" 2011 "ari"]]} {("a" 2010) [["a" 2010 "jon"]]}) )
Expected/Desired result (notice the sequence, NOT a sequence within a sequence as above):
({("a" 2011) [["a" 2011 "dan"] ["a" 2011 "ari"]]} {("a" 2010) [["a" 2010 "jon"]]})
Note: The expected result is a sequence of maps; each map is comprised of composite keys and nested vectors.
Upvotes: 1
Views: 145
Reputation: 8172
The reason that you are getting a sequence within another sequence is that for
returns a lazy seq. Because it is called every time collapse
encounters a map and the map you provide nests two levels deep you're getting sequences nested two levels deep.
Quick fix: put a flatten
in front of the for
like so:
(defn collapse [data & keys-coll]
(if (map? data)
(flatten
(for [[k v] data]
(collapse v (conj keys-coll k))))
(hash-map (flatten keys-coll) data))
(Note that you can also get rid of the if
statement). Maybe not the most elegant solution, but suffering from a brain freeze right now ...
Upvotes: 1