数组需要删除基于键值对的重复对象,还需要返回sum[fidle]



需要根据匹配的键删除重复的对象,但要添加值。已经创建了snippet和fiddle来查看。还在底部添加了预期结果。

我尝试了几种不同的方法,但都没能得到想要的结果。我可以使用filter方法,但不能为匹配的键添加值。请看一看小提琴或片段

小提琴链接这里

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);

使用reduce&Object.assign((可以得到想要的结果。解释作为注释添加到代码中。

注意我使用Object.assign作为curr = Object.assign({}, x);而不是curr = x;,因为稍后使用curr = x;,当我们在查找现有对象的同时更新value时,它也会更新data2value。使用Object.assign({}, x);不会发生这种情况。

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);

Ciao,您可以尝试获得不同的areaName.value,然后在data2上迭代以求和area.value,如:

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)

带有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);

最新更新