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
-~----------~----~----~----~------~----~------~--~---

Reply via email to