0

I'm trying to merge objects with the same key value into one and count them. Is it even possible?

    var array = {
"items": [{
    "value": 10,
    "id": "111",
    "name": "BlackCat",
}, {
    "value": 10,
    "id": "111",
    "name": "BlackCat",
}, {
    "value": 15,
    "id": "777",
    "name": "WhiteCat",
}]
}

Desired output:

    var finalArray = {
"items": [{
    "value": 10,
    "id": "111",
    "name": "BlackCat",
    "count": 2,
}, {
    "value": 15,
    "id": "777",
    "name": "WhiteCat",
    "count": 1,
}]
}
Alue
  • 63
  • 1
  • 2
  • 7
  • 3
    Anythin you've tried on yourself so far? – Aer0 Feb 07 '17 at 14:42
  • The object "array" has 1 array inside, with 3 objetcs (like a JSON), why is that? can you modified and use just an array of objects? I think that using array.filter and map would do the trick – pmiranda Feb 07 '17 at 14:45
  • I spent the whole day, can't figure it out unfortunately – Alue Feb 07 '17 at 14:45
  • Did you check this? http://stackoverflow.com/questions/33850412/merge-javascript-objects-in-array-with-same-key – pmiranda Feb 07 '17 at 14:46

4 Answers4

4

You can use reduce on your items array:

var combinedItems = array.items.reduce(function(arr, item) {
    var found = false;

    for (var i = 0; i < arr.length; i++) {
        if (arr[i].id === item.id) {
            found = true;
            arr[i].count++;
        }
    }

    if (!found) {
        item.count = 1;
        arr.push(item);
    }

    return arr;
}, [])

Fiddle: https://jsfiddle.net/6wqw79pn/

tymeJV
  • 103,943
  • 14
  • 161
  • 157
0

You could use a for loop:

var finalArray = [];
for (var i in array.items) {
  var item = array.items[i];
  var existingItem = finalArray.find(function(element){
    return (element.id == item.id);
  });
  if (!existingItem) {
    existingItem = {};
    finalArray.push(existingItem);
  } else {
    if (!existingItem.count)
      existingItem.count = 2;
    else
      existingItem.count++;
  }
  for (var j in item) {
    existingItem[j] = item[j];
  }
}

Working example: https://jsfiddle.net/mspinks/5kowbq4j/3/

Matt Spinks
  • 6,380
  • 3
  • 28
  • 47
0

Basically you could use a hash table with the value of id as key and count.

var object = { items: [{ value: 10, id: "111", name: "BlackCat", }, { value: 10, id: "111", name: "BlackCat", }, { value: 15, id: "777", name: "WhiteCat", }] },
result = object.items.reduce(function (hash) {
    return function (r, o) {
        if (!hash[o.id]) {
            hash[o.id] = { value: o.value, id: o.id, name: o.name, count: 0 };
            r.push(hash[o.id]);
        }
        hash[o.id].count++;
        return r;
    };
}(Object.create(null)), []);
 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Underscore js will be able to solve your problem very easily

var groups = _.groupBy(array.items, function(item){
    return item.value + '#' + item.id + '#' + item.name;
});

var data = {'items' : []};

_.each(groups,function(group){
    data.items.push({
      'value' : group[0].value,
      'id' : group[0].id,
      'name' : group[0].name,
      'count' : group.length
    })
})

console.log(data)
Vignesh Murugan
  • 575
  • 5
  • 18