Michael Tot Korsgaard
Michael Tot Korsgaard

Reputation: 4014

merge array object together - lodash

So I have an array of items like this:

items = [
    {
        amount: 2,
        name: 'bike'
    },
    {
        amount: 1,
        name: 'boat'
    },
    {
        amount: 3,
        name: 'bike'
    }
]

Now, I would like to merge this array so that there would be no duplicates of bike and still know how many bikes there are in total.

so my result array would look like this:

items = [
    {
        amount: 5,
        name: 'bike'
    },
    {
        amount: 1,
        name: 'boat'
    }
]

In order to keep my code short I have been advised using lodash and I've been looking at the different ways to merge arrays together. But to be honest it quite confusing to figure out what the best approach would be, which is why I'm asking you guys ^^

Upvotes: 4

Views: 527

Answers (2)

Oleksandr T.
Oleksandr T.

Reputation: 77482

You can use .groupBy with .map, and _.sum for calculate amount, like so

var items = [{
    amount: 2,
    name: 'bike'
}, {
    amount: 1,
    name: 'boat'
}, {
    amount: 3,
    name: 'bike'
}];

var res = _(items)
    .groupBy('name')
    .map(function (el, name) {
        return {
            name: name,
            amount: _.sum(el, 'amount')
        };
    })    
    .value();

console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.7.0/lodash.min.js"></script>
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

Upvotes: 4

Andy
Andy

Reputation: 63514

If you didn't want to load lodash in specifically for this example (not sure the extra 50K is worth your while here for a couple of extra lines of code) here's a vanilla JS version that uses a temporary object to hold the values while you loop over the various objects:

function merge(items) {
    var tmp = {}, out = [];
    for (var i = 0, l = items.length; i < l; i++) {
        var name = items[i].name;
        var amount = items[i].amount;
        if (!tmp[name]) tmp[name] = 0;
        tmp[name] += amount;
    }
    for (var p in tmp) {
        out.push({ name: p, amount: tmp[p] });
    }
    return out;
}

merge(items); // [{"name":"bike","amount":5},{"name":"boat","amount":1}]

DEMO

Upvotes: 3

Related Questions