Reputation: 393
need to remove duplicate objects based on matching keys but add values. have created snippet and fiddle to take a look at. Also have added the expected result at the bottom.
I have tried few different things but unable to get desired results. I can use filter method but then cannot add values for matching keys. Please take a look at fiddle or snippet
let data2 = [{
area: {
type: "double",
value: 50
},
areaName: {
type: "string",
value: "westside"
},
areaTitle: {
type: "string",
value: "rock"
}
},
{
area: {
type: "double",
value: 250
},
areaName: {
type: "string",
value: "north"
},
areaTitle: {
type: "string",
value: "sand"
}
},
{
area: {
type: "double",
value: 400
},
areaName: {
type: "string",
value: "westside"
},
areaTitle: {
type: "string",
value: "rock"
}
}
];
var filterData2 = Object.keys(data2).reduce((acc, elem) => {
let getKeys = data2[elem];
console.log(getKeys);
return acc;
}, []);
console.log(filterData2);
// Expected result
let result = [{
Area: {
type: "double",
value: 450
},
AreaName: {
type: "string",
value: "westside"
},
AreaTitle: {
type: "string",
value: "rock"
}
},
{
Area: {
type: "double",
value: 250
},
AreaName: {
type: "string",
value: "north"
},
AreaTitle: {
type: "string",
value: "sand"
}
}
]
console.log(result);
Upvotes: 3
Views: 76
Reputation: 2946
A solution with find:
let data2 = [{
area: {
type: "double",
value: 50
},
areaName: {
type: "string",
value: "westside"
},
areaTitle: {
type: "string",
value: "rock"
}
},
{
area: {
type: "double",
value: 250
},
areaName: {
type: "string",
value: "north"
},
areaTitle: {
type: "string",
value: "sand"
}
},
{
area: {
type: "double",
value: 400
},
areaName: {
type: "string",
value: "westside"
},
areaTitle: {
type: "string",
value: "rock"
}
}
];
let result = [];
let found = null;
data2.forEach( x => {
found = result.find( y => x.areaName.value === y.areaName.value && x.areaTitle.value === y.areaTitle.value);
if (found){
found.area.value += x.area.value;
} else {
// option1: simple
// result.push(x);
// option2: controlling side effects
result.push({
area: { value: x.area.value, type: x.area.type },
areaName: x.areaName,
areaTitle:x.areaTitle
});
}
});
// Expected result
let expected = [{
Area: {
type: "double",
value: 450
},
AreaName: {
type: "string",
value: "westside"
},
AreaTitle: {
type: "string",
value: "rock"
}
},
{
Area: {
type: "double",
value: 250
},
AreaName: {
type: "string",
value: "north"
},
AreaTitle: {
type: "string",
value: "sand"
}
}
]
console.log(result,expected);
Upvotes: 1
Reputation: 12629
Using reduce & Object.assign() like below you can get desired result. Explanation is added as comment in code.
Note I used Object.assign
as curr = Object.assign({}, x);
instead of curr = x;
because with curr = x;
later when we update value
while finding existing object it will also update value
of data2
. Using Object.assign({}, x);
this will not happen.
let data2 = [{
area: {
type: "double",
value: 50
},
areaName: {
type: "string",
value: "westside"
},
areaTitle: {
type: "string",
value: "rock"
}
},
{
area: {
type: "double",
value: 250
},
areaName: {
type: "string",
value: "north"
},
areaTitle: {
type: "string",
value: "sand"
}
},
{
area: {
type: "double",
value: 400
},
areaName: {
type: "string",
value: "westside"
},
areaTitle: {
type: "string",
value: "rock"
}
}
];
// use reduce to iterate over array and produce result
var result = data2.reduce((a, x) => {
// find matching object from a.
let curr = a.filter(y => y.areaName.value == x.areaName.value && y.areaTitle.value == x.areaTitle.value)[0];
// if not exists then create new object and add into a
// else add value to curr.area.value
if (!curr) {
curr = Object.assign({}, x);
a.push(curr);
} else {
curr.area.value += x.area.value;
}
// return a
return a;
}, []);
console.log(result);
Upvotes: 1
Reputation: 11156
Ciao, you could try to get distinct areaName.value
and then iterate on data2
to sum area.value
like:
let data2 = [{
area: {
type: "double",
value: 50
},
areaName: {
type: "string",
value: "westside"
},
areaTitle: {
type: "string",
value: "rock"
}
},
{
area: {
type: "double",
value: 250
},
areaName: {
type: "string",
value: "north"
},
areaTitle: {
type: "string",
value: "sand"
}
},
{
area: {
type: "double",
value: 400
},
areaName: {
type: "string",
value: "westside"
},
areaTitle: {
type: "string",
value: "rock"
}
}
];
let areas = [...new Set(data2.map(el => el.areaName.value))];
let result = [];
areas.forEach(area => {
let dataToSum = data2.filter(el => el.areaName.value === area)
let obj = {};
let areasum = 0
dataToSum.forEach(el => {
areasum += el.area.value;
})
obj.area = {type: dataToSum [0].area.type, value: areasum}
obj.areaName = {type: dataToSum [0].areaName.type, value: area}
obj.areaTitle = {type: dataToSum [0].areaTitle.type, value: dataToSum [0].areaTitle.value}
result.push(obj)
})
console.log(result)
Upvotes: 1