我有一个这样的嵌套对象:
var itemsWithQuantities = [
{
Identifier: 'SomethingWithQuantities1',
Quantities: [
{ Name: 'Quantity 1', Amount: 4 },
{ Name: 'Quantity 2', Amount: 1 },
{ Name: 'Quantity 3', Amount: 3 }
]
},
{
Identifier: 'SomethingWithQuantities2',
Quantities: [
{ Name: 'Quantity 1', Amount: 3 },
{ Name: 'Quantity 2', Amount: 2 },
{ Name: 'Quantity 3', Amount: 5 }
]
}
];
问题:我想弃去所有的金额'对象一起获取[7, 3, 8]
,将其视为Amount
字段的水平和。我想干净利落地使用方法链。
我现有的解决方案没有方法链是这样的:
var amountSumsNoChain = _.reduce(_.map(itemsWithQuantities, function(item) {
return _.pluck(item.Quantities, 'Amount');
}), function (prevQ, nextQ) {
return [
prevQ[0] + nextQ[0],
prevQ[1] + nextQ[1],
prevQ[2] + nextQ[2]
];
}, [0, 0, 0]);
到目前为止,使用Lo-Dash' _.partialRight
获得的最干净的解决方案是:
var amountSumsChain = _.chain(itemsWithQuantities)
.pluck('Quantities')
.map(function(a){return _.partialRight(_.pluck, 'Amount')(a);})
.reduce(function(p,c){return [p[0] + c[0], p[1] + c[1], p[2] + c[2]];}).value();
在第三行,.map
调用,有没有办法简化该行?
为什么我不能使用.map(_.partialRight(_.pluck, 'Amount'))
? _.partialRight
应该返回一个函数,它需要一个pluck参数,正如你所看到的,它在上面的方法链中工作,但是有一个显式的闭包函数。有没有办法让它更简洁?
答案 0 :(得分:5)
为什么我不能使用
.map(_.partialRight(_.pluck, 'Amount'))
?_.partialRight
应该返回一个需要pluck
的一个参数的函数。
不幸的是,不完全是partialRight
因此而被打破。如果我们查看the docs,他们已经指出了会发生什么:
将部分参数附加到提供给新函数的那些
在源代码中查看确认新函数不仅仅期望一个参数,而是任意数量的参数,只是将部分给定的参数附加到它们。由于map
确实使用项目,索引和集合调用其回调,因此这些回调恰好传递给pluck
:
_.map([[{Amount:3}[], _.partialRight(_.pluck, 'Amount'))
// is actually equivalent to
[ _.pluck([{Amount:3}], 0, [[{Amount:3}]], 'Amount') ]
// which will pluck the "0" property, not "Amount":
[ [ undefined ] ]
它只适用于显式闭包函数
[它实际上没有关闭,因为它没有自由变量。]是的,该函数有效,因为您只将一个参数显式传递给部分应用的函数。实际上你不再需要部分应用它,但可以使用
.map(function(a) { return _.pluck(a, 'Amount'); })
有没有办法让它更简洁?
要避免使用函数表达式,可以使用createCallback
来限制参数计数:
.map(_.createCallback(_.partialRight(_.pluck, 'Amount'), null, 1))
不确定这是否更好。