I am new to Clojure programming, and would like to know what is the idiomatic way to do the following thing:
I would like to sum a collection of numbers nums
, which may contains a large number of numbers, let's assume there are only positive numbers.
I don't care the exact sum if the sum is very large. For example, if the sum of the numbers is larger than 9999, I would simply return 10000 without summing the remaining numbers at all.
If I implement it with some OO language such as Java, I may do it like below:
private int sum(int[] nums) {
int sum = 0;
for(int n : nums) {
if(sum > 9999) {
sum = 10000;
break;
} else {
sum += n;
}
}
return sum;
}
A naive implementation in Clojure may look like:
(let [sum (reduce + nums)]
(if (> sum 9999) 10000 sum))
However, this seems to waste some CPU resource to sum the entire collection of numbers, which is not desired. I am looking for something like take-while function but for reduce, but cannot find it. Is there something like:
(reduce-while pred f val coll)
Or is there any other Clojure idiomatic way to solve this problem? I think the solution can be applied to a set of problems requiring similar logic.
Any comment is appreciated. Thanks.
If you're using Clojure 1.5.x then you may take advantage of new reduced
function:
(reduce #(if (> %1 9999) (reduced 10000) (+ %1 %2)) nums)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With