nums = [2 5 3 7]
result = []
result.push {x:nums[0]}
for n in nums.slice(1)
result.push {n:n + result[-1].x}
log result
# [{x:2} {x:7} {x:10} {x:17}]
使用函数 map
在功能上难以表达,因为每个元素都依赖于前一个元素。对于这个算法来说,什么是正确的函数式解决方案呢?
nums = [2 5 3 7]
result = []
result.push {x:nums[0]}
for n in nums.slice(1)
result.push {n:n + result[-1].x}
log result
# [{x:2} {x:7} {x:10} {x:17}]
使用函数 map
在功能上难以表达,因为每个元素都依赖于前一个元素。对于这个算法来说,什么是正确的函数式解决方案呢?
我知道的最简单方法避免了性能下降的闭包、变量、额外的函数开销和全局变量:
result= [2, 5, 3, 7].map(function(a){ return { x: this[0]+=a }; }, [0]);
JS 提供了很少使用的第二个 .map() 参数,用于在迭代之间存储所需的任何状态。
这可能再简单不过了,但我不知道咖啡是什么,抱歉...
编辑:制作了一个双语(js+cs)演示:http://pagedemos.com/maptranforms/
result = [2,5,3,7].map ((a) -> x: @[0] += a), [0]
- mutilscan1
方法:nums = [2 5 3 7]
scan1 (+), nums |> map ((num) -> { x : num })
# => [{x: 2}, {x: 7}, {x: 10}, {x: 17}]
scan1 (+), [2 5 3 7] # => [2, 7, 10, 17]
你需要在某个地方保存一些状态信息。以下是一个JavaScript闭包,它可以完成这项工作:
var nums = [2, 5, 3, 7];
var result = nums.map(
(function() {
var lastX = 0;
return function(n) {
return {x : (lastX += n)};
}
}())
);
// result is [{x:2} {x:7} {x:10} {x:17}]
dandavis
在 Coffeescript 中的答案如下:
nums.map ((x)->{x: @[0] += x}), [0]
nums.map ((x)->{x: @accum += x}), {accum:0}
coffeescript
理解(并且使用相同的累加器思想)。accum = 0; z = ({x: accum += i} for i in nums)
JavaScript
保持一个计数器,每次只需添加新数字即可:
var nums = [2,5,3,7];
var createObject = function(nums){
var result = [],
total = 0;
for(var i = 0; i < nums.length; i++){
total += nums[i];
result.push({"x": total});
}
return result;
};
map (-> {x:it}) <| (fold ((acc, a) -> acc ++ [a + ((last acc) ? 0)]), []) <| [2, 5, 3, 7]
result.push {x:n + result[-1].x}
吗? - Ted Hoppmap
只是fold
的一个特例,而fold
是更通用的循环。使用fold
,你可以做到你所要求的。 - kqr