Reputation: 1938
I'm trying to find the very last of the first elements of sequence which satisfy a given predicate, in Clojure.
I use the following code at the moment:
(last (take-while pred (gimme-potentially-infinite-seq ...)))
Unfortunately, (take-while ...)
holds onto head, causing me out-of-memory in some cases.
I could you use loop/if/recur
combo to solve that, but maybe there's some function (or combination of functions) in clojure.core that does exactly that?
UPDATE: it's not take-while
which is holding onto head but last
.
UPDATE 2: I tested this (->> (range) (take 10000000) last)
in Clojure REPL and ClojureScript REPLs (Planck 2.0.0 and Lumo 1.1.0). There's major heap growth for Planck (2 GB of RAM) and Lumo (1.5 GB), while there's minor heap growth on the JVM (200-300 MB).
Upvotes: 3
Views: 186
Reputation: 29958
Just build it up slowly:
(def data (range 9999))
(defn is-evil? [x]
(= 666 (mod x 1000))) ; is the number like xxxx666
(def all-matching-nums
(filter is-evil? data))
all-matching-nums => (666 1666 2666 3666 4666 5666 6666 7666 8666 9666)
(last all-matching-nums) => 9666
Of course, the filter
step will never terminate if your sequence is truly infinite. That is another problem!
Upvotes: 1