开发者

build set lazily in clojure

开发者 https://www.devze.com 2023-02-25 16:45 出处:网络
I\'ve started to learn clojure but I\'m having trouble wrapping my mind around certain concepts. For instance, what I want to do here is to take this function and convert it so that it calls get-origl

I've started to learn clojure but I'm having trouble wrapping my mind around certain concepts. For instance, what I want to do here is to take this function and convert it so that it calls get-origlabels lazily.

(defn get-all-origlabels []
    (set (flatten (map get-origlabels (range *song-count*)))))

My first attempt used recursion but blew up the stack (song-count is about 10,000). I couldn't figure out how to do it with tail recursion.

get-origlabels returns a set each time it is called, but values are often re开发者_开发问答peated between calls. What the get-origlabels function actually does is read a file (a different file for each value from 0 to song-count-1) and return the words stored in it in a set.

Any pointers would be greatly appreciated!

Thanks! -Philip


You can get what you want by using mapcat. I believe putting it into an actual Clojure set is going to de-lazify it, as demonstrated by the fact that (take 10 (set (iterate inc 0))) tries to realize the whole set before taking 10.

(distinct (mapcat get-origlabels (range *song-count*)))

This will give you a lazy sequence. You can verify that by doing something like, starting with an infinite sequence:

(->> (iterate inc 0)
     (mapcat vector)
     (distinct)
     (take 10))

You'll end up with a seq, rather than a set, but since it sounds like you really want laziness here, I think that's for the best.


This may have better stack behavior

(defn get-all-origlabels []
    (reduce (fn (s x) (union s (get-origlabels x))) ${} (range *song-count*)))


I'd probably use something like:

(into #{} (mapcat get-origlabels (range *song-count*)))

In general, "into" is very helpful when constructing Clojure data structures. I have this mental image of a conveyor belt (a sequence) dropping a bunch of random objects into a large bucket (the target collection).

0

精彩评论

暂无评论...
验证码 换一张
取 消