0

I have two arrays of objects

array = [
 {
  "id_0":356,
  "name":"India",
  "key1":150
 },
 {
  "id_0":356,
  "name":"India",
  "key2":200
 },
 {
  "id_0":748,
  "name":"Swaziland",
  "key1":140
 },
 {
  "id_0":748,
  "name":"Swaziland",
  "key2":180
 }
]

I am trying to find the duplicate id_0 in array of objects and merge the duplicate object of key2 and value.

I want the result to be:

array = [
 {
  "id_0":356,
  "name":"India",
  "key1":150,
  "key2":200
 },
 {
  "id_0":748,
  "name":"Swaziland",
  "key1":140,
  "key2":180
 }
]

How to find the duplicate value and merge the duplicate key and value in array?

1
  • 1
    The name becomes india from India, also, what if the dupls have same attribute, what did you expect its outcome, for example, if the first item also has key2: 123, what will the result be? Commented Dec 11, 2015 at 9:54

3 Answers 3

3

You can use Array.prototype.reduce() to reduce your array as you need.

Duplicate item can be merged using Object.assign().

var array = [
    { 'id_0': 356, 'name': 'India', 'key1': 150 },
    { 'id_0': 356, 'name': 'India', 'key2': 200 }
];

var result = array.reduce(function(prev, item) {
    var newItem = prev.find(function(i) {
        return i.id_0 === item.id_0; 
    });
    if (newItem) {
        Object.assign(newItem, item);
    } else {
        prev.push(item);
    }
    return prev;
}, []);

console.log(result);

Object.assign is part of ES6. If it does not work for you, just replace it with:

for (var attrname in item) {
    newItem[attrname] = item[attrname];
};
Sign up to request clarification or add additional context in comments.

Comments

3

Try this fiddle

var array = [
 {
  "id_0":356,
  "name":"India",
  "key1":150
 },
 {
  "id_0":356,
  "name":"India",
  "key2":200
 },
 {
  "id_0":356,
  "name2":"china",
  "key2":200
 }
]
function mergeArray( arr )
{
   var outputObj = {};
   for ( var counter = 0; counter < arr.length; counter++ )
   {
      var obj = arr[ counter ];
      for( var key in obj )
      {
         if ( !outputObj[ key ] )
         {
           outputObj[ key ] = obj[ key ];
         }
      }
   }
   return outputObj;
}
console.log( mergeArray( array ) );

Edited the fiddle to suit your 'UPDATED' requirement

var array = [
 {
  "id_0":356,
  "name":"India",
  "key1":150
 },
 {
  "id_0":356,
  "name":"India",
  "key2":200
 },
 {
  "id_0":400,
  "name2":"china",
  "key2":200
 },
 {
  "id_0":400,
  "name2":"china",
  "key2":200
 }
]
function mergeArray( arr )
{
   var outputObj = {};
   for ( var counter = 0; counter < arr.length; counter++ )
   {
      var obj = arr[ counter ];
      for( var key in obj )
      {
         if ( !outputObj[ key ] )
         {
           outputObj[ key ] = obj[ key ];
         }
      }
   }
   return outputObj;
}
function collateArray( arr )
{
   var outputObj = {};
   var result = [];
   for ( var counter = 0; counter < arr.length; counter++ )
   {
      var obj = arr[ counter ];
      var id_0value = obj[ "id_0" ];
      if ( !outputObj[ id_0value ] )
      {
        outputObj[ id_0value ] = [];
      }
      outputObj[ id_0value ].push( obj );
   }
   console.log( outputObj );
   for ( var key in outputObj )
   {
      result.push( mergeArray( outputObj[ key ] ) );
   }
   return result;

}
console.log( collateArray( array ) );

2 Comments

@elango what about other properties which are common between objects
see result is group by id_0, i have different id_0 is available in array of objects so i want group by id_0
0

Use an temp Object as a map that stores key => item can make the time complexity to O(n):

var arr = [
 {
  "id_0":356,
  "name":"India",
  "key1":150
 },
 {
  "id_0":356,
  "name":"India",
  "key2":200
 },
 {
  "id_0":748,
  "name":"Swaziland",
  "key1":140
 },
 {
  "id_0":748,
  "name":"Swaziland",
  "key2":180
 }
];

// items:            the array to be merged to unique.
// attrName:    the attribute's name that is for distinguish,
// isOverwrite:decides whether the value will be overwrite by later ones or not. Default to false. 
function getUnique(items, attrName, isOverwrite) {
  // Map to keep reference to objects by its id.
  var store = {};
  // The array for output result.
  var result = [];
  
  isOverwrite = !!isOverwrite;
  
  items.forEach(function(item) {
    var id = item[attrName];
    var key;
    
    // Try to fetch item by id from store.
    var target = store[id];
    
    // If target item exist in store, its dulplicated, we need to merge it.
    if (typeof target !== 'undefined') {
      // If it's presented, we need to merge it into existing one.
      for (key in item) {
        if (!item.hasOwnProperty(key)) {
          continue;
        }
        
        // If isOverwrite is true, always use the newest value, otherwise,
        // we only apply values that are not exist in target yet.
        if (isOverwrite || typeof target[key] === 'undefined') {
          target[key] = item[key];
        }
      }
    } else {
      // If its not in store yet, put it a clone into result, and to map for 
      // later reference.
      var clone = {};
      for (key in item) {
        if (item.hasOwnProperty(key)) {
          clone[key] = item[key];
        }        
      }
      store[id] = clone;      
      // Also put it into the result array.
      result.push(clone);
   }
  });

  return result;
}

console.log(getUnique(arr, 'id_0'));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.