I am reducing the data array down to one entry per DishName with Qty, Cooked and NotCooked values added together if the DishNames are the same.
What I have works, however due to needing compatibility with old devices I cannot use .find() with "fat arrows". I've tried racking my brain but cannot come up with a solution.
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);
The var existItem = acc.find(item => item.DishName === obj.DishName); can be rewritten without arrow function as
var existItem = acc.find(function(item){return item.DishName === obj.DishName;});
Or if you want to avoid using find as
var existItem = acc.filter(function(item){return item.DishName === obj.DishName;})[0];
But i would also change acc.push(obj); to acc.push({...obj}); to avoid mutating the original data array.
Arrow functions are slightly different than regular functions but are very similar. In your case, you can just use find with a regular function.
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);
An approach free of find has the additional advantage of saving for each step of a full reduce cycle the unnecessary find iteration.
A solution based on an accumulator which does take care of mapping and collecting un/merged dish-items runs just a single reduce cycle.
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; }