如何按 属性 对对象进行分组,同时对另一个对象求和
How to group objects by some property while summing another
我尝试了很多方法来解决这个问题。我可以删除重复值。但问题是更新 total_product 值。我怎样才能做到这一点?给我一些提示。
这是我的主阵列:
const colors = [
{ "name": "Black", "total_product": 1 },
{ "name": "Black", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
]
我想要这样的:
const colors = [
{ "name": "Black", "total_product": 2 },
{ "name": "White", "total_product": 4 }
]
您可以使用 new Map()
或简单对象来存储相同对象的计数:
const colors = [
{ "name": "Black", "total_product": 1 },
{ "name": "Black", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
];
const colorsMap = new Map();
colors.forEach(color => {
if (colorsMap.has(color.name)) {
colorsMap.set(color.name, colorsMap.get(color.name) + 1);
return;
}
colorsMap.set(color.name, 1);
});
const groupedColors = [];
colorsMap.forEach((value, key) => {
groupedColors.push({
name: key,
total_product: value
});
})
console.log(groupedColors);
reduce
是一个很好的例子,它将数组“归结”为累加器值。在这里,reduce (doc) 可用于创建计算每个名称出现次数的对象...
const colors = [
{ "name": "Black", "total_product": 1 },
{ "name": "Black", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 }
];
const counts = colors.reduce((acc, obj) => {
if (!acc[obj.name]) acc[obj.name] = { name: obj.name, total_product: 0 };
acc[obj.name].total_product++;
return acc;
}, {});
const result = Object.values(counts);
console.log(result);
reduce 产生的中间值 counts
看起来像这样...
{
"Black": {
"name": "Black",
"total_product": 2 // <- incremented each time we found a "Black"
},
"White": {
"name": "White",
"total_product": 4 // <- incremented each time we found a "White"
}
}
Object.values()
,顾名思义,生成一个值数组。
const colors = [
{ name: "Black", total_product: 1 },
{ name: "Black", total_product: 1 },
{ name: "White", total_product: 1 },
{ name: "White", total_product: 1 },
{ name: "White", total_product: 1 },
{ name: "White", total_product: 1 }
];
const uniqueColors = (colors) => {
const unique = [];
colors.map((color) => {
const index = unique.findIndex((c) => c.name === color.name);
if (index === -1) {
unique.push(color);
} else {
unique[index].total_product++;
}
});
return unique;
};
console.log(uniqueColors(colors));
return 数组没有任何意义,因为您已经 将数组压缩 为唯一的名称及其各自的值,只需简化为对象:
const colors = [
{name:"Black", total_product:1},
{name:"Black", total_product:1},
{name:"White", total_product:1},
{name:"White", total_product:1},
{name:"White", total_product:1},
{name:"White", total_product:1},
];
const sumColors = colors.reduce((ob, item) => {
ob[item.name] ??= 0
ob[item.name] += item.total_product;
return ob;
}, {});
console.log(sumColors); // {"Black": 2, "White": 4}
我尝试了很多方法来解决这个问题。我可以删除重复值。但问题是更新 total_product 值。我怎样才能做到这一点?给我一些提示。
这是我的主阵列:
const colors = [
{ "name": "Black", "total_product": 1 },
{ "name": "Black", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
]
我想要这样的:
const colors = [
{ "name": "Black", "total_product": 2 },
{ "name": "White", "total_product": 4 }
]
您可以使用 new Map()
或简单对象来存储相同对象的计数:
const colors = [
{ "name": "Black", "total_product": 1 },
{ "name": "Black", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
];
const colorsMap = new Map();
colors.forEach(color => {
if (colorsMap.has(color.name)) {
colorsMap.set(color.name, colorsMap.get(color.name) + 1);
return;
}
colorsMap.set(color.name, 1);
});
const groupedColors = [];
colorsMap.forEach((value, key) => {
groupedColors.push({
name: key,
total_product: value
});
})
console.log(groupedColors);
reduce
是一个很好的例子,它将数组“归结”为累加器值。在这里,reduce (doc) 可用于创建计算每个名称出现次数的对象...
const colors = [
{ "name": "Black", "total_product": 1 },
{ "name": "Black", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 },
{ "name": "White", "total_product": 1 }
];
const counts = colors.reduce((acc, obj) => {
if (!acc[obj.name]) acc[obj.name] = { name: obj.name, total_product: 0 };
acc[obj.name].total_product++;
return acc;
}, {});
const result = Object.values(counts);
console.log(result);
reduce 产生的中间值 counts
看起来像这样...
{
"Black": {
"name": "Black",
"total_product": 2 // <- incremented each time we found a "Black"
},
"White": {
"name": "White",
"total_product": 4 // <- incremented each time we found a "White"
}
}
Object.values()
,顾名思义,生成一个值数组。
const colors = [
{ name: "Black", total_product: 1 },
{ name: "Black", total_product: 1 },
{ name: "White", total_product: 1 },
{ name: "White", total_product: 1 },
{ name: "White", total_product: 1 },
{ name: "White", total_product: 1 }
];
const uniqueColors = (colors) => {
const unique = [];
colors.map((color) => {
const index = unique.findIndex((c) => c.name === color.name);
if (index === -1) {
unique.push(color);
} else {
unique[index].total_product++;
}
});
return unique;
};
console.log(uniqueColors(colors));
return 数组没有任何意义,因为您已经 将数组压缩 为唯一的名称及其各自的值,只需简化为对象:
const colors = [
{name:"Black", total_product:1},
{name:"Black", total_product:1},
{name:"White", total_product:1},
{name:"White", total_product:1},
{name:"White", total_product:1},
{name:"White", total_product:1},
];
const sumColors = colors.reduce((ob, item) => {
ob[item.name] ??= 0
ob[item.name] += item.total_product;
return ob;
}, {});
console.log(sumColors); // {"Black": 2, "White": 4}