Obviously, this cannot be done completely lazy since changing the
first element is not a stopping time. You'll always need at least one
lookahead to determine the change of the key and you'll have to
realize the input to find all values for a key.
(defn grouped-seq
[input]
(lazy-seq
(when-let [s (seq input)]
(let [k (ffirst s)
[vs r] (split-with #(-> % first (= k)) s)]
(cons [k vs] (grouped-seq r))))))
(map #(apply callbackListener %) (grouped-seq [["tom" 32] ["tom" 2333]
["anne" 12] ["anne" 55]]))
Note: if you try to avoid realizing all values of a given key, you'll
need two sequences: one to keep track of the key and of for the
values. While callbackListener realises the values, the key sequence
will retain the head of the input causing all values to stay in
memory. If you want really laziness, you'll have to traverse the input
twice over independent input streams. So if you have a file containing
the data, you'll have to read the file twice from independent streams
to get full laziness.
Sincerely
Meikel
Hi! How would you solve such problem:I have a collection of pairs (key, value) ->[ [ "tom" 32 ] [ "tom" 2333 ] [ "anne" 12 ] [ "anne" 55 ] ]As you can see keys can occur more than once, also that collection is very large so it should be evaluated lazily (for example the collection cames from stream input).I have function with two arguments key and sequence of its values, the pseudo code would be:callbackListener(string key, iterator values)now I would like get such effect that callbackListener will be called twice for the example collection.once with "tom" and iterator (or a lazy seq) to lazy evaluated collection of (32 and 2333)and second with "anne" and iterator for collection of (12 and 55)