Last active
October 25, 2018 13:45
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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