繁体   English   中英

如何在javascript中分组或合并此对象数组?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM