On Nov 8, 12:33 pm, Michael Jaaka <michael.ja...@googlemail.com> wrote: > > 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) <snip> > Note that all must be evaluated lazily.
Unless the keys in your sequence will always be sorted, I don't believe you can do this lazily; in order to generate a sequence of the values for a given key in your collection, you would have to traverse the entire collection first in order to check each key, i.e. if you had: [[ "tom" 32 ] [ "anne" 12 ] [ "anne" 55 ] [ "tom" 2333 ]] Then you'd need to get right to the end of the list in order to generate the sequence of values for "tom". One, non-lazy, way to accomplish what you're after would be: (use '[clojure.contrib.seq-utils :only (group-by)]) (def *s* [["tom" 32] ["tom" 2333] ["anne" 12] ["anne" 55]]) (defn callback-listener [k v] (println (str "key: " k ", value: " v))) (doseq [[k v] (map (fn [[k v]] [k (map second v)]) (group-by first *s*))] (callback-listener k v)) Note that since you used the name "callback-listener", I'm assuming that it has side effects, which is why I used doseq. If callback- listener does _not_ have side effects (i.e. if it performs some computation upon it's arguments and simply yields a result, then you could use: (defn callback-fn [[k v]] (compute-some-value-from-arguments k v)) (map (comp callback-fn (fn [[k v]] [k (map second v)])) (group-by first *s*)) which would yield a sequence of the result of each call to callback- fn2. Note that while the resulting sequence would, technically, be lazy, group-by is not, so you would still consume the entire input sequence up front. Now, _if_ you can guarantee that your input sequence will always be sorted by key (that is, if you know for a fact that all the entries for a given key will be consecutive, as in your example: [tom tom anne anne], rather than mine above: [tom anne tom anne]), then you could use partition-by instead, which would (I believe) let you achieve full laziness: (use '[clojure.contrib.seq-utils :only (partition-by)]) (map (comp callback-fn (fn [part] [(ffirst part) (map second part)])) (partition-by first *s*)) Hope this helps, -David --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---