[英]Group by array of objects by a nested key
I have the following data:我有以下数据:
const data = [
{
parent: {
id: "1",
name: "Europe"
},
item: {
name: "Italy"
},
score: 5
},
{
parent: {
id: "1",
name: "Europe"
},
item: {
name: "France"
},
score: 4.5
},
{
parent: {
id: "1",
name: "Europe"
},
item: {
name: "UK"
},
score: 4.9
},
{
parent: {
id: "2",
name: "Afrique"
},
item: {
name: "Morocco"
},
score: 3.1
},
{
parent: {
id: "2",
name: "Afrique"
},
item: {
name: "Egypt"
},
score: 3.9
}
];
I want to group it based on the parent.id
and calculate the average score, so I can have the following result:我想根据
parent.id
对其进行parent.id
并计算平均分数,因此我可以得到以下结果:
[
{
parent: {
id: "1",
name: "Europe",
items: [
{
name: "Italy"
},
{
name: "France"
},
{
name: "UK"
}
],
score: 4.8
}
},
{
parent: {
id: "2",
name: "Afrique",
items: [
{
name: "Morocco"
},
{
name: "Egypt"
}
],
score: 3.5
}
}
]
I used the following function, but it doesn't work for the nested key, and also it's doesn't return the desired result schema.我使用了以下函数,但它不适用于嵌套键,而且它也不会返回所需的结果模式。
let group = cars.reduce((r, a) => {
console.log("a", a);
console.log('r', r);
r[a.make] = [...r[a.parent.id] || [], a];
return r;
}, {});
console.log("group", group);
You can use _reduce()
function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce您可以使用
_reduce()
函数: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
var result = data.reduce((res, data) => {
if(!res[data.parent.id]) {
data.item = [data.item];
res[data.parent.id] = data;
} else {
res[data.parent.id]['item'].push(data['item']);
res[data.parent.id]['score'] = (res[data.parent.id]['score'] + data['score'])/2;
}
return res;
}, [])
.filter(x => x != null)
const data = [ { parent: { id: "1", name: "Europe" }, item: { name: "Italy" }, score: 5 }, { parent: { id: "1", name: "Europe" }, item: { name: "France" }, score: 4.5 }, { parent: { id: "1", name: "Europe" }, item: { name: "UK" }, score: 4.9 }, { parent: { id: "2", name: "Afrique" }, item: { name: "Morocco" }, score: 3.1 }, { parent: { id: "2", name: "Afrique" }, item: { name: "Egypt" }, score: 3.9 } ]; var result = data.reduce((res, data) => { if(!res[data.parent.id]) { data.item = [data.item]; res[data.parent.id] = data; } else { res[data.parent.id]['item'].push(data['item']); res[data.parent.id]['score'] = (res[data.parent.id]['score'] + data['score'])/2; } return res; }, []) .filter(x => x != null) console.log(result)
Create an object/hashmap, then format the resulting object into an array.创建一个对象/哈希图,然后将结果对象格式化为一个数组。
let continents = {}
data.forEach(function(country){
const continent_id = country.parent.id
let continent = continents[continent_id]
if(!continent){
continent = {
id: continent_id,
name: country.parent.name,
items: [],
}
continents[continent_id] = continent
}
continent.items.push({
name: country.item.name,
score: country.score
})
})
continents = Object.entries(continents).map(item => ({parent: item[1]}))
console.log(continents)
Output:输出:
[
{
"parent":{
"id":"1",
"name":"Europe",
"items":[
{
"name":"Italy",
"score":5
},
{
"name":"France",
"score":4.5
},
{
"name":"UK",
"score":4.9
}
]
}
},
{
"parent":{
"id":"2",
"name":"Afrique",
"items":[
{
"name":"Morocco",
"score":3.1
},
{
"name":"Egypt",
"score":3.9
}
]
}
}
]
From the data you've provided if you additionaly need to count average of score
property, use the following reduce method: it will iterate trough your data, group it and calculate total score value and count of score values.根据您提供的数据,如果您还需要计算
score
属性的平均值,请使用以下 reduce 方法:它将遍历您的数据,对其进行分组并计算总分值和分值计数。 And after reduce groups object perform map that will calculate average for score for all the groups using totalScore
and scoreCount
在减少组对象执行映射后,将使用
totalScore
和scoreCount
计算所有组的totalScore
scoreCount
const data = [ { parent: { id: "1", name: "Europe" }, item: { name: "Italy" }, score: 5 }, { parent: { id: "1", name: "Europe" }, item: { name: "France" }, score: 4.5 }, { parent: { id: "1", name: "Europe" }, item: { name: "UK" }, score: 4.9 }, { parent: { id: "2", name: "Afrique" }, item: { name: "Morocco" }, score: 3.1 }, { parent: { id: "2", name: "Afrique" }, item: { name: "Egypt" }, score: 3.9 } ]; let group = data.reduce((acc, rec) => { if (acc.find(item => item.parent.id === rec.parent.id)) { const idx = acc.findIndex(item => item.parent.id === rec.parent.id) acc[idx].parent.items = acc[idx].parent.items.concat(rec.item) acc[idx].parent.score += rec.score acc[idx].parent.scoreCount +=1 } else { acc = acc.concat({parent: {...rec.parent, score: rec.score, items: [rec.item], scoreCount:1}}) } return acc }, []).map(it => ({parent: {id: it.parent.id, name:it.parent.name, score: (it.parent.score / it.parent.scoreCount), items: it.parent.items}})); console.log("group", group);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.