[英]How to group or merge this array of objects in javascript?
我有一个像下面这样的对象数组。
{name: "Mc Donald", quantity: 4, maleCount: 1, femaleCount: 0}
{name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}
{name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}
{name: "Mc Donald", quantity: 4, maleCount: 0, femaleCount: 1}
{name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1}
{name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}
{name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1}
{name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1}
我想将它们分组并加总其中的所有值。 例如,最终将是这样的:
{name: "Mc Donald", quantity: 8, maleCount: 1, femaleCount: 1}
{name: "KFC", quantity: 54, maleCount: 3, femaleCount: 3}
如何在JavaScript中实现?
我试图在网上找到一些解决方案,但这不是我想要的。 例如这个解决方案
您可以使用数组减少:
var arr = [ {name: "Mc Donald", quantity: 4, maleCount: 1, femaleCount: 0}, {name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}, {name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}, {name: "Mc Donald", quantity: 4, maleCount: 0, femaleCount: 1}, {name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1}, {name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}, {name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1}, {name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1} ]; var finalArr = arr.reduce((m, o) => { var found = m.find(p => p.name === o.name); if (found) { found.quantity += o.quantity; found.maleCount += o.maleCount; found.femaleCount += o.femaleCount; } else { m.push(o); } return m; }, []); console.log(finalArr);
您可以使用forEach()
循环并添加到新数组。 您可以将空对象作为thisArg
参数传递,并可以在回调函数中使用this
,并且在第二个forEach上下文中,由于箭头函数, this
仍将与第一个回调函数相同。
var data = [{"name":"Mc Donald","quantity":4,"maleCount":1,"femaleCount":0},{"name":"KFC","quantity":9,"maleCount":1,"femaleCount":0},{"name":"KFC","quantity":9,"maleCount":1,"femaleCount":0},{"name":"Mc Donald","quantity":4,"maleCount":0,"femaleCount":1},{"name":"KFC","quantity":9,"maleCount":0,"femaleCount":1},{"name":"KFC","quantity":9,"maleCount":1,"femaleCount":0},{"name":"KFC","quantity":9,"maleCount":0,"femaleCount":1},{"name":"KFC","quantity":9,"maleCount":0,"femaleCount":1}] var result = [], keys = ['quantity', 'maleCount', 'femaleCount'] data.forEach(function(e) { if(!this[e.name]) result.push(this[e.name] = e); else keys.forEach(k => this[e.name][k] += e[k]) }, {}) console.log(result)
您可以与哈希表进行分组,并为具有可变值的键使用数组。
var array = [{ name: "Mc Donald", quantity: 4, maleCount: 1, femaleCount: 0 }, { name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0 }, { name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0 }, { name: "Mc Donald", quantity: 4, maleCount: 0, femaleCount: 1 }, { name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1 }, { name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0 }, { name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1 }, { name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1 }], groups = Object.create(null), result = array.reduce(function (r, o) { var values = ['quantity', 'maleCount', 'femaleCount']; if (!groups[o.name]) { groups[o.name] = { name: o.name }; r.push(groups[o.name]); values.forEach(function (k) { groups[o.name][k] = 0; }); } values.forEach(function (k) { groups[o.name][k] += o[k]; }); return r; }, []); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
使用linq.js
var array = [{ name: "Mc Donald", quantity: 4, maleCount: 1, femaleCount: 0 }, { name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0 }, { name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0 }, { name: "Mc Donald", quantity: 4, maleCount: 0, femaleCount: 1 }, { name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1 }, { name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0 }, { name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1 }, { name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1 }], result = Enumerable.From(array) .GroupBy( "$.name", null, "{ name: $.Key, quantity: $$.Sum('$.quantity'), maleCount: $$.Sum('$.maleCount'), femaleCount: $$.Sum('$.femaleCount') }" ) .ToArray(); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>
我的解决方案基于reduce:
let data = [ {name: "Mc Donald", quantity: 4, maleCount: 1, femaleCount: 0}, {name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}, {name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}, {name: "Mc Donald", quantity: 4, maleCount: 0, femaleCount: 1}, {name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1}, {name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}, {name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1}, {name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1} ]; // We will only keep an array of values of the merged object let result = Object.values( // Merge data to name indexed objects data.reduce((p,c) => { // Ensure key (name) exists if (!p[c.name]) { // If first occurence, duplicate object (to avoid modification of original array) p[c.name] = Object.assign({}, c); } else { // If key (name) already exists, sum up relevant attributes p[c.name].quantity += c.quantity; p[c.name].maleCount += c.maleCount; p[c.name].femaleCount += c.femaleCount; } // return updated object return p; }, {}) ); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
希望这会有所帮助
更多功能/通用方法
const normalizeValue = (value) => value === undefined ? 0 : value const sumUpProps = (props = []) => (a = {}, b = {}) => { const result = {} props.forEach((prop) => { result[prop] = normalizeValue(a[prop]) + normalizeValue(b[prop]) }) return result } const data = [ {name: "Mc Donald", quantity: 4, maleCount: 1, femaleCount: 0}, {name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}, {name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}, {name: "Mc Donald", quantity: 4, maleCount: 0, femaleCount: 1}, {name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1}, {name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0}, {name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1}, {name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1} ] const entries = {} const sumObjects = sumUpProps(['quantity', 'maleCount', 'femaleCount']) data.forEach((item) => { const entry = entries[item.name] || {} entries[item.name] = sumObjects(entry, item) }) console.log(entries)
检查以下代码:
var array = [
{name: "Mc Donald", quantity: 4, maleCount: 1, femaleCount: 0},
{name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0},
{name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0},
{name: "Mc Donald", quantity: 4, maleCount: 0, femaleCount: 1},
{name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1},
{name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0},
{name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1},
{name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1},
];
var result = [];
for(var index in array){
var obj = array[index];
if(result.hasOwnProperty(obj.name)) {
result[obj.name].quantity += obj.quantity;
result[obj.name].maleCount += obj.maleCount;
result[obj.name].femaleCount += obj.femaleCount;
}else{
result[obj.name] = {};
result[obj.name].quantity = obj.quantity;
result[obj.name].maleCount = obj.maleCount;
result[obj.name].femaleCount = obj.femaleCount;
}
}
console.log(result);
这是使用干净现代JavaScript的通用解决方案:
function groupRestaurants(restaurants) { const groups = new Map(); restaurants.forEach(restaurant => { const group = findOrCreateGroup(groups, restaurant.name); addRestaurantToGroup(group, restaurant); }); return [...groups.values()]; } function findOrCreateGroup(groups, name) { let group = groups.get(name); if (!group) { group = { name }; groups.set(name, group); } return group; } function addRestaurantToGroup(group, restaurant) { for (const [key, value] of Object.entries(restaurant)) { if (key !== 'name') { if (group.hasOwnProperty(key)) { group[key] += value; } else { group[key] = value; } } } } const restaurants = [ { name: "Mc Donald", quantity: 4, maleCount: 1, femaleCount: 0 }, { name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0 }, { name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0 }, { name: "Mc Donald", quantity: 4, maleCount: 0, femaleCount: 1 }, { name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1 }, { name: "KFC", quantity: 9, maleCount: 1, femaleCount: 0 }, { name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1 }, { name: "KFC", quantity: 9, maleCount: 0, femaleCount: 1 } ]; console.log(groupRestaurants(restaurants));
Lodash使您的生活变得轻松。
_.map(_.groupBy(yourArrayHere, 'name'), (groupMembers, groupKey) => {
let sumObject = {name: groupKey};
_.forEach(['quantity', 'maleCount', 'femaleCount'], (property) => {
sumObject[property] = 0;
_.forEach(groupMembers, (member) => {
sumObject[property] += member[property];
});
});
return sumObject;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.