Keys are always sorted. So once a key stops appearing it won't appear again. The first solution seems to be the right one, because all values are processed in a sequence manner in a lazy way.
2009/11/8 DTH <dth...@gmail.com> > > 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 -~----------~----~----~----~------~----~------~--~---