Skip to content

Instantly share code, notes, and snippets.

@manutter51
Last active October 25, 2018 13:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manutter51/3e000c8d19ea4ae17d64b17302a40975 to your computer and use it in GitHub Desktop.
Save manutter51/3e000c8d19ea4ae17d64b17302a40975 to your computer and use it in GitHub Desktop.
Hand-rolled lazy seq for pairing inner values to outer keys in a map nested 1 layer deep with other maps.
(def mm {1 {101 :a 102 :b 103 :c} 2 {201 :aa 202 :bb}})
;; possible cases
;; fully populated {1 {11 :a, 12 :b}, 2 {21 :a, 22 :b}}
;; single inner value {1 {12 :b}, 2 {21 :a, 22 b}}
;; empty inner value, multi-entry outer {1 {}, 2 {21 :a, 22 :b}}
;; other degenerate cases that boil down to either "the first key-value pair has data to process" or "We're done."
(defn outer-inners
"Give a lazy sequence of outer/inner pairs, given a map of values nested
one layer deep."
([] nil)
;; evil destructuring :) pulls off the first key/value pair and puts them
;; into outer-k/outer-v, then puts the rest of the map in a seq of k/v pairs.
;; We'll keep it as a seq so we can easily conj the updated first k/v pair
;; back in at the head.
([[[outer-k outer-v] & outer-more]]
(cond
;; check for end-of seq
(and (nil? (seq outer-v))
(nil? (seq outer-more)))
nil ;; Nothing left to iterate thru, end of seq
;; check for nothing left in current value of first key in outer
(nil? (seq outer-v))
(outer-inners (into {} outer-more)) ;; non-lazy recursive continue with rest of outer
;; if we made it this far, we can make a lazy seq
:else
;; evil destructuring again, except this time we don't care about the rest,
;; since we'll get it back by dissoc'ing from outer-v
(let [[[inner-k inner-v] & _] outer-v
;;
new-outer-v (dissoc outer-v inner-k)
new-outer (into {} (conj outer-more [outer-k new-outer-v]))]
(lazy-seq (cons [outer-k inner-v] (outer-inners new-outer))))
)))
(outer-inners mm)
;; => ([1 :a] [1 :b] [1 :c] [2 :aa] [2 :bb])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment