执行函数直到特定条件成立
我想重复地将某个函数应用于某个状态,直到条件成立。
函数 f 接受一个状态,修改它并返回它。再次将 f 应用于返回的状态,依此类推。
我认为这会起作用。
(first (filter pred (iterate f x)))
但有点难看。另外,内存消耗并不理想,因为迭代器将被迫评估并保留中间状态,直到返回 pred 为 true 的状态,此时应该对中间状态进行垃圾收集。
我知道您可以编写一个简单的递归函数:
(loop [f x p] (if (p x) x (recur f (f x) p))
但我正在寻找一个核心库函数(或某些函数组合),它可以以相同的内存效率执行相同的操作。
I want to repeatedly apply some function to some state until a condition holds true.
Function f takes a state, modifies it and returns it. Apply f again to the returned state and so on.
I think this would work.
(first (filter pred (iterate f x)))
But it's a bit ugly. Plus memory consumption is not ideal since iterator would be forced to evaluate and keep intermediate states until the state on which pred holds true is returned, at which point intermediate states should be garbage collected.
I know you can write a simple recursive function:
(loop [f x p] (if (p x) x (recur f (f x) p))
But I'm looking for a core library function (or some combination of functions) that does the same thing with the same memory efficiency.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
你真正想要的是 take-while:
编辑
使用高阶函数来实现您想要的结果的一种方法可能是将您的函数包装到由
trampoline
使用的东西中,即返回最终结果或另一个函数的函数这将执行下一步。代码如下:迭代执行如下:
What you really want is take-while:
EDIT
A way to use higher order functions to achieve the result you want might be to wrap your function into something to be consumed by
trampoline
, namely a function that will either return the final result or another function which will execute the next step. Here's the code:The iterative execution would go as follows:
不确定您所说的迭代器是什么意思 - 您使用它就像它是迭代器一样,我只是想确定这就是您的意思。无论如何,你的解决方案对我来说看起来很好,而且一点也不难看。而且内存也不是问题:只要方便,
iterate
就可以随意丢弃中间结果,因为您没有保留对它们的任何引用,只需在其中调用filter
即可。 “流”方式。Not sure what you mean by
iterator
- you're using it as if it wereiterate
, and I just want to be sure that's what you mean. At any rate, your solution looks fine to me and not at all ugly. And memory is not an issue either:iterate
is free to throw away intermediate results whenever it's convenient because you aren't keeping any references to them, just callingfilter
on it in a "streaming" way.我认为你应该让你的循环成为一个简单的递归函数:
I think you should just make your loop a simple recursive function:
下降时怎么样
How about drop-while
我认为没有一个核心功能可以准确有效地完成此任务。因此,我将使用循环/递归来执行此操作,如下所示:
循环/递归非常高效,因为它不需要额外的存储,并且在 JVM 中作为简单循环实现。
如果您要经常这样做,那么您始终可以将模式封装在宏中。
I don't think there is a core function that does this exactly and efficiently. Hence I would do this with loop/recur as follows:
Loop/recur is very efficient since it requires no additional storage and is implemented as a simple loop in the JVM.
If you're going to do this a lot, then you can always encapsulate the pattern in a macro.
听起来你想要
while
宏。http://richhickey.github.com/clojure/clojure .core-api.html#clojure.core/while
在稍微不同的用例中,
for
宏也支持 :when 和 :while 选项。http://richhickey.github.com/clojure/clojure .core-api.html#clojure.core/for
Sounds like you want the
while
macro.http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/while
In a slightly different use case the
for
macro supports :when and :while options too.http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/for