3

I have an array populated with objects. How do I go about merging objects inside this array when they have a matching specific sub value?

My array looks like this:

var data = [
    {
        prod_name:"test1", type:"1", color:"white", product_id:"5"
    },
    {
        prod_name:"test2", type:"1", color:"green", product_id:"7"
    },
    {
        prod_name:"test2", type:"2", color:"green", product_id:"7"
    },
    {
        prod_name:"test3", type:"4", color:"red", product_id:"8"
    },
    {
        prod_name:"test4", type:"2", color:"white", product_id:"21"
    }    
];

I want to merge the objects based on a matching product_id .

In case the values are not the same, I want to keep BOTH values, seperated with a comma. So the outcome of the previous array would become:

[
    {
        prod_name:"test1", type:"1", color:"white", product_id:"5"
    },
    {
        prod_name:"test2", type:"1,2", color:"green", product_id:"7"
    },
    {
        prod_name:"test3", type:"4", color:"red", product_id:"8"
    },
    {
        prod_name:"test4", type:"2", color:"white", product_id:"21"
    }    
];

The array shrunk with 1 because it had a duplicate, and the two values that where not the same are merged and seperated by a comma type:"1,2" .

I thought the following would work:

jQuery.each( data, function( i, val ) {
    var productID = val.product_id;
    var index_key = i;
    jQuery.each( data, function( i, val ) {
        if(val.product_id == productID && data[index_key] != data[i]){
            jQuery.extend(data[index_key], data[i]);
        }
    });
});

But this only overwrites the type value of the first hit and keeps both entries.

For "mergable" items the values prod_name and product_id are always the same.

Does anyone know of a way to achieve the desired result?

UPDATE: Different values(product attributes) might be added in a later stage. Therefor I'd prefer a method that does not specifically check for the type attribute, but rather checks for eveything that is NOT product_id or prod_name and if it has a hit, merges this with a comma.

FIDDLE

timo
  • 2,119
  • 1
  • 24
  • 40

1 Answers1

1

What I do in example bellow., first I create object to achieve unique values (by project_id), and then converted object to array. In first loop I check if item does not exists in res - put to res, else I change only property type

var res = {};

$.each(data, function (key, value) {
    if (!res[value.product_id]) {
        res[value.product_id] = value;    
    } else {
        res[value.product_id].type = [
          res[value.product_id].type, 
          value.type
        ].join(',');
    }
});

data = $.map(res, function (value) {
  return value;
}); 

console.log(data);

Example

Oleksandr T.
  • 76,493
  • 17
  • 173
  • 144