使用reducer而不使用find的对象值合计数组



如果DishNames相同,我将data数组减少到每个DishName与Qty, Cooked和NotCooked值一起添加的一个条目。

我所拥有的作品,但是由于需要与旧设备兼容,我不能使用.find()与"脂肪箭头"。我已经绞尽脑汁了,但还是想不出一个解决办法。

var data = [
{ DishName: '35. Chicken Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0 },
{ DishName: '36. Lamb Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0 },
{ DishName: '37. Prawn Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0 },
{ DishName: '38. King Prawn Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0 },
{ DishName: '35. Chicken Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1 },
{ DishName: '36. Lamb Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1 },
{ DishName: '37. Prawn Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1 },
{ DishName: 'Chicken Tikka Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1 },
];
var res = data.reduce(function(acc, obj) {
var existItem = acc.find(item => item.DishName === obj.DishName);
if (existItem) {
existItem.Qty += obj.Qty;
existItem.Cooked += obj.Cooked;
existItem.NotCooked += obj.NotCooked;
return acc;
}
acc.push(obj);
return acc;
}, []);
console.log(res);

不带箭头函数的var existItem = acc.find(item => item.DishName === obj.DishName);可以重写为

var existItem = acc.find(function(item){return item.DishName === obj.DishName;});

或者如果您想避免使用find作为

var existItem = acc.filter(function(item){return item.DishName === obj.DishName;})[0];

但我也会改变acc.push(obj);acc.push({...obj});,以避免改变原来的data数组。

箭头函数与常规函数略有不同,但非常相似。在您的情况下,您可以将find与常规函数一起使用。

var data =
[
{DishName: '35. Chicken Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0},
{DishName: '36. Lamb Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0},
{DishName: '37. Prawn Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0},
{DishName: '38. King Prawn Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0},
{DishName: '35. Chicken Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1},
{DishName: '36. Lamb Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1},
{DishName: '37. Prawn Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1},
{DishName: 'Chicken Tikka Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1},
]

var res = data.reduce(function(acc, obj) {
var existItem = acc.find(function(item){return item.DishName === obj.DishName});
if (existItem) {
existItem.Qty += obj.Qty;
existItem.Cooked += obj.Cooked;
existItem.NotCooked += obj.NotCooked;
return acc;
}
acc.push(obj);
return acc;
}, []);
console.log(res);

一个没有find的方法还有一个额外的好处,那就是在一个完整的reduce循环的每一步都节省了不必要的find迭代。

一个基于累加器的解决方案,它负责映射和收集未合并的碟子项,只运行一个reduce循环。

function mergeSameDish(collector, item) {
var index = collector.index;
var list = collector.list;
var merger = index[item.DishName];
if (merger) {
// a (to be) merged dish item.
merger.Qty = merger.Qty + item.Qty;
merger.Cooked = merger.Cooked + item.Cooked;
merger.NotCooked = merger.NotCooked + item.NotCooked;
} else {
// collect and map a shallow dish item copy
// in order to not later mutate the original.
list.push(
index[item.DishName] = Object.assign({}, item)
);
}
return collector;
}
var data = [
{ DishName: '35. Chicken Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0 },
{ DishName: '36. Lamb Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0 },
{ DishName: '37. Prawn Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0 },
{ DishName: '38. King Prawn Vindaloo', Qty: 1, Cooked: 1, NotCooked: 0 },
{ DishName: '35. Chicken Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1 },
{ DishName: '36. Lamb Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1 },
{ DishName: '37. Prawn Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1 },
{ DishName: 'Chicken Tikka Vindaloo', Qty: 1, Cooked: 0, NotCooked: 1 },
];
console.log(
'mutated/reduced items ...',
data.reduce(mergeSameDish, {
index: {},
list: [],
}).list
);
console.log('unchanged/original items ... ', data);
.as-console-wrapper { min-height: 100%!important; top: 0; }

最新更新