如何在Clojure中找到满足给定谓词的序列第一个元素的最后一个?
我试图在Clojure中找到满足给定谓词的序列的最后一个元素 我目前使用以下代码:如何在Clojure中找到满足给定谓词的序列第一个元素的最后一个?,clojure,Clojure,我试图在Clojure中找到满足给定谓词的序列的最后一个元素 我目前使用以下代码: (last (take-while pred (gimme-potentially-infinite-seq ...))) 不幸的是,(花些时间…抓住头部,在某些情况下导致我的内存不足 我可以使用loop/if/recurcombo来解决这个问题,但clojure.core中可能有一些函数(或函数组合)可以做到这一点 更新:不是抓住头部的take-while,而是last 更新2:我在Clojure REPL和
(last (take-while pred (gimme-potentially-infinite-seq ...)))
不幸的是,(花些时间…
抓住头部,在某些情况下导致我的内存不足
我可以使用loop/if/recur
combo来解决这个问题,但clojure.core中可能有一些函数(或函数组合)可以做到这一点
更新:不是抓住头部的take-while
,而是last
更新2:我在Clojure REPL和ClojureScript REPLs(Planck 2.0.0和Lumo 1.1.0)中测试了这个
(>(范围)(最后取10000000)
。普朗克(2 GB的RAM)和Lumo(1.5 GB)的堆增长较大,而JVM(200-300 MB)的堆增长较小。只需慢慢构建即可:
(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
当然,如果您的序列确实是无限的,
filter
步骤永远不会终止。这是另一个问题 我可能错过了什么。。。但是,您怎么能期望在无限序列中找到满足谓词的最后一个元素呢?你必须扫描整个序列才能得到结果。你能解释一下为什么你认为last
能抓住头部吗?您的调用在堆使用率不变(没有无限增长)的情况下对我有效。@glts这似乎是ClojureScript(请参阅上面的更新)。您假设第一个元素符合条件。否则,您将得到nil
。满意吗?@Thumbnail是的,没错。在我看来,过滤器
步骤总是终止-它很懒惰。请看:惰性序列宏将其主体捕获为未计算的函数。如果过滤后的序列是无限的,last
不会终止。无论如何,它是所需的第一个最大顺应元素子序列的最后一个;不是整个序列的最后一个兼容元素。