Hi,

Am 08.11.2009 um 13:33 schrieb Michael Jaaka:

> 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)
>
> In Java it is easy because the language is imperative. But how about  
> such logic in Clojure?
> Note that all must be evaluated lazily.

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

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to