简体   繁体   中英

sum up object properties in array of objects into a single object Lodash

I have been trying to get this right and was having issues so figured i should ask ppl with more experience. I have an array of objects lets say called items, and I need to sum up some of the properties across different objects in the array and sum them up those at the end. The user can make a few selections and i need to only sum up the only the chosen properties in the array they give me so i thought maybe to use the _.pick function in lodash. If possible i would like to do that in one loop since the items array could have upto a 1000 items. Here is an example:

var items = [
{'lightBlue':4, 'darkBlue':2, 'red':4, 'orange':6, 'purple':7},
{'lightBlue':6, 'darkBlue':5, 'red':1, 'orange':2, 'purple':3},
{'lightBlue':2, 'darkBlue':4, 'red':3, 'orange':4, 'purple':9}
]

var userSelectedColors = ['lightBlue', 'darkBlue'];

What I want to see is all the blue's summed up like:

var summedUp = [{'lightBlue':12, 'darkBlue':11}];

Then sum up the results to get the total no

var totalCount = 23

Whats the best and performant way to get this in lodash. The array of userSelectedColors could be 1 or any combination of the colors.

Please provide an example, thanks your helps appreciated!

Use _.sumBy

var totalCount = _.sumBy(userSelectedColors, _.partial(_.sumBy, items));

 var items = [ { 'lightBlue': 4, 'darkBlue': 2, 'red': 4, 'orange': 6, 'purple': 7 }, { 'lightBlue': 6, 'darkBlue': 5, 'red': 1, 'orange': 2, 'purple': 3 }, { 'lightBlue': 2, 'darkBlue': 4, 'red': 3, 'orange': 4, 'purple': 9 } ], userSelectedColors = ['lightBlue', 'darkBlue']; var totalCount = _.sumBy(userSelectedColors, _.partial(_.sumBy, items)); console.log(totalCount); 
 <script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script> 

Expanded, that looks like:

var totalCount = _.sumBy(userSelectedColors, function(prop) {
    return _.sumBy(items, prop);
});

Without Lodash, a more performant solution would be something like this:

var totalCount = items.reduce(function(total, obj) {
    return total + userSelectedColors.reduce(function(total, prop) {
        return total + obj[prop];
    }, 0);
}, 0);

 var items = [ { 'lightBlue': 4, 'darkBlue': 2, 'red': 4, 'orange': 6, 'purple': 7 }, { 'lightBlue': 6, 'darkBlue': 5, 'red': 1, 'orange': 2, 'purple': 3 }, { 'lightBlue': 2, 'darkBlue': 4, 'red': 3, 'orange': 4, 'purple': 9 } ], userSelectedColors = ['lightBlue', 'darkBlue']; var totalCount = items.reduce(function(total, obj) { return total + userSelectedColors.reduce(function(total, prop) { return total + obj[prop]; }, 0); }, 0); console.log(totalCount); 
 <script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script> 

In terms of efficiency, I believe this is hard to beat, since it only iterates once through the array, but it's not quite as succinct as an approach like the one @4castle took. (Also, for only 1000 items, you're never going to notice the performance difference anyway.)

var items = [
    {'lightBlue':4, 'darkBlue':2, 'red':4, 'orange':6, 'purple':7},
    {'lightBlue':6, 'darkBlue':5, 'red':1, 'orange':2, 'purple':3},
    {'lightBlue':2, 'darkBlue':4, 'red':3, 'orange':4, 'purple':9}
]

var userSelectedColors = ['lightBlue', 'darkBlue'];

var sums = {};

_.each(items, function (item) {
    _.each(userSelectedColors, function (color) {
        sums[color] = (sums[color] || 0) + item[color];
    });
});

console.log('Summary: ', sums);

console.log('Grand total: ', _.sum(_.values(sums)));

Output:

Summary:  { lightBlue: 12, darkBlue: 11 }
Grand total:  23

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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