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
很难在功能上表达,因为每个元素都依赖于前一个元素。该算法的正确功能解决方案是什么?
答案 0 :(得分:18)
我知道的最简单的方法避免了性能抢夺闭包,变量,额外的函数开销和全局变量:
result= [2, 5, 3, 7].map(function(a){ return { x: this[0]+=a }; }, [0]);
JS提供了很少使用的第二个.map()参数来存储迭代之间所需的任何状态。
它可能没有比这更简单,但不知道咖啡,对不起......
编辑:掀起双语(js + cs)演示:http://pagedemos.com/maptranforms/
答案 1 :(得分:8)
您所描述的是扫描:折叠也会返回中间结果。使用prelude.ls中的scan1
:
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]
答案 2 :(得分:3)
您需要在某处保留一些状态信息。这是一个完成工作的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}]
答案 3 :(得分:2)
<强>的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;
};
答案 4 :(得分:2)
dandavis
答案是:
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)
答案 5 :(得分:1)
map (-> {x:it}) <| (fold ((acc, a) -> acc ++ [a + ((last acc) ? 0)]), []) <| [2, 5, 3, 7]