我正在使用CoffeeScript将列表中的元素聚合到组合对象中。但是,当我有两个相同的值时,其中一个值将被忽略。不是跳过其中一个值,而是如何得到它们的总和?
metals = [
{ metal: 'silver', amount: 10 }
{ metal: 'gold', amount: 16 }
{ metal: 'iron', amount: 17 }
{ metal: 'iron', amount: 3 }
]
reduction = metals.reduce (x, y) ->
x[y.metal]= y.amount
x
, {}
console.log reduction
# => { silver: 10, gold: 16, iron: 3 }, but I would like to get iron: 20
这是一个帮助解决问题{jsfiddle} {/ 3}}
答案 0 :(得分:2)
如果您希望reduce
总结一下,那么您必须这样说:
reduction = metals.reduce (x, y) ->
x[y.metal] = (x[y.metal] ? 0) + y.amount
x
, { }
x[y.metal] ? 0
只是说"如果x[y.metal]
已定义,则使用它,否则使用0
"。你也可以说:
reduction = metals.reduce (x, y) ->
x[y.metal] = (x[y.metal] || 0) + y.amount
x
, { }
因为您不关心x[y.metal]
的{false}值,例如0
,''
,false
,null
或{{1 }};在你的情况下,你可以将所有这些转换为零。
您还可以更明确地了解自己在做什么:
undefined
如果reduction = metals.reduce (x, y) ->
x[y.metal] = 0 if(y.metal !of x)
x[y.metal] += y.amount
x
, {}
已经没有x[y.metal] = 0 if(y.metal !of x)
属性,x[y.metal]
只会将x
初始化为零。如果您不喜欢y.metal
:
unless
!of
请记住,所有reduction = metals.reduce (x, y) ->
x[y.metal] = 0 unless(y.metal of x)
x[y.metal] += y.amount
x
, {}
都会运行您提供的功能,并将功能的输出反馈给自己:
reduce
只是:
[1,2,3].reduce f, i
f(f(f(i, 1), 2), 3)
函数对其输入的作用以及它返回的内容取决于您。