我是Clojure编程的新手,想知道做以下事情的惯用方法是什么:
我想总结一组数字nums,其中可能包含大量数字,我们假设只有正数.
如果总和非常大,我不在乎确切的总和.例如,如果数字的总和大于9999,我只返回10000而不总计剩余的数字.
如果我用一些OO语言(如Java)实现它,我可以这样做:
private int sum(int[] nums) {
int sum = 0;
for(int n : nums) {
if(sum > 9999) {
sum = 10000;
break;
} else {
sum += n;
}
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
Clojure中的一个简单实现可能如下所示:
(let [sum (reduce + nums)]
(if (> sum 9999) 10000 sum))
Run Code Online (Sandbox Code Playgroud)
但是,这似乎浪费了一些CPU资源来汇总整个数字集合,这是不希望的.我正在寻找像take-while函数但是为了减少,但找不到它.是否有类似的东西:
(reduce-while pred f val coll)
Run Code Online (Sandbox Code Playgroud)
或者还有其他任何Clojure惯用方法来解决这个问题吗?我认为该解决方案可以应用于需要类似逻辑的一组问题.
任何评论表示赞赏.谢谢.
Leo*_*tny 16
如果您使用的是Clojure 1.5.x,那么您可以利用新reduced功能:
(reduce #(if (> %1 9999) (reduced 10000) (+ %1 %2)) nums)
Run Code Online (Sandbox Code Playgroud)
xsc*_*xsc 10
其中一个鲜为人知的Clojure功能似乎是reductions.它将为您提供计算的所有中间结果:
(reductions + (range 4)) ;; => (0 1 2 3)
(reduce + (range 4)) ;; => 3
Run Code Online (Sandbox Code Playgroud)
reductions'结果seq 的最后一个元素将是减少的值.有多种方法可以强制执行谓词,例如some:
(let [sums (reductions + nums)]
(if (some #(> % 9999) sums)
10000
(last sums)))
Run Code Online (Sandbox Code Playgroud)
@ leonid-beschastny给出的reduce/ reduced版本可能更快(没有懒惰的序列开销,缩减器......),但是这个版本也适用于早期的Clojure版本.
| 归档时间: |
|
| 查看次数: |
1049 次 |
| 最近记录: |