[javascript] How to concatenate properties from multiple JavaScript objects

I am looking for the best way to "add" multiple JavaScript objects (associative arrays).

For example, given:

a = { "one" : 1, "two" : 2 };
b = { "three" : 3 };
c = { "four" : 4, "five" : 5 };

what is the best way to compute:

{ "one" : 1, "two" : 2, "three" : 3, "four" : 4, "five" : 5 }

This question is related to javascript object dictionary associative-array

The answer is


It's easy using ES7 spread operator for an object, in your browser console put

({ name: "Alex", ...(true  ? { age: 19 } : { })}) // {name: "Alex", age: 19}
({ name: "Alex", ...(false ? { age: 19 } : { })}) // {name: "Alex",        }

function Collect(a, b, c) {
    for (property in b)
        a[property] = b[property];

    for (property in c)
        a[property] = c[property];

    return a;
}

Notice: Existing properties in previous objects will be overwritten.


You could use jquery's $.extend like this:

_x000D_
_x000D_
let a = { "one" : 1, "two" : 2 },_x000D_
    b = { "three" : 3 },_x000D_
    c = { "four" : 4, "five" : 5 };_x000D_
_x000D_
let d = $.extend({}, a, b, c)_x000D_
_x000D_
console.log(d)
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
_x000D_
_x000D_
_x000D_


Simplest: spread operators

var obj1 = {a: 1}
var obj2 = {b: 2}
var concat = { ...obj1, ...obj2 } // { a: 1, b: 2 }

This should do it:

_x000D_
_x000D_
function collect() {_x000D_
  var ret = {};_x000D_
  var len = arguments.length;_x000D_
  for (var i = 0; i < len; i++) {_x000D_
    for (p in arguments[i]) {_x000D_
      if (arguments[i].hasOwnProperty(p)) {_x000D_
        ret[p] = arguments[i][p];_x000D_
      }_x000D_
    }_x000D_
  }_x000D_
  return ret;_x000D_
}_x000D_
_x000D_
let a = { "one" : 1, "two" : 2 };_x000D_
let b = { "three" : 3 };_x000D_
let c = { "four" : 4, "five" : 5 };_x000D_
_x000D_
let d = collect(a, b, c);_x000D_
console.log(d);
_x000D_
_x000D_
_x000D_

Output:

{
  "one": 1,
  "two": 2,
  "three": 3,
  "four": 4,
  "five": 5
}

ECMAScript 6 has spread syntax. And now you can do this:

_x000D_
_x000D_
const obj1 = { 1: 11, 2: 22 };_x000D_
const obj2 = { 3: 33, 4: 44 };_x000D_
const obj3 = { ...obj1, ...obj2 };_x000D_
_x000D_
console.log(obj3); // {1: 11, 2: 22, 3: 33, 4: 44}
_x000D_
_x000D_
_x000D_


ES6 ++

The question is adding various different objects into one.

let obj = {};
const obj1 = { foo: 'bar' };
const obj2 = { bar: 'foo' };
Object.assign(obj, obj1, obj2);
//output => {foo: 'bar', bar: 'foo'};

lets say you have one object with multiple keys that are objects:

let obj = {
  foo: { bar: 'foo' },
  bar: { foo: 'bar' }
}

this was the solution I found (still have to foreach :/)

let objAll = {};

Object.values(obj).forEach(o => {
  objAll = {...objAll, ...o};
});

By doing this we can dynamically add ALL object keys into one.

// Output => { bar: 'foo', foo: 'bar' }

Probably, the fastest, efficient and more generic way is this (you can merge any number of objects and even copy to the first one ->assign):

function object_merge(){
    for (var i=1; i<arguments.length; i++)
       for (var a in arguments[i])
         arguments[0][a] = arguments[i][a];
   return arguments[0];
}

It also allows you to modify the first object as it passed by reference. If you don't want this but want to have a completely new object containing all properties, then you can pass {} as the first argument.

var object1={a:1,b:2};
var object2={c:3,d:4};
var object3={d:5,e:6};
var combined_object=object_merge(object1,object2,object3); 

combined_object and object1 both contain the properties of object1,object2,object3.

var object1={a:1,b:2};
var object2={c:3,d:4};
var object3={d:5,e:6};
var combined_object=object_merge({},object1,object2,object3); 

In this case, the combined_object contains the properties of object1,object2,object3 but object1 is not modified.

Check here: https://jsfiddle.net/ppwovxey/1/

Note: JavaScript objects are passed by reference.


To merge a dynamic number of objects, we can use Object.assign with spread syntax.

const mergeObjs = (...objs) => Object.assign({}, ...objs);

The above function accepts any number of objects, merging all of their properties into a new object with properties from later objects overwriting those from previous objects.

Demo:

_x000D_
_x000D_
const mergeObjs = (...objs) => Object.assign({}, ...objs);
const a = {prop: 1, prop2: '2'},
      b = {prop3: 3, prop4: [1,2,3,4]}
      c = {prop5: 5},
      d = {prop6: true, prop7: -1},
      e = {prop1: 2};
const abcd = mergeObjs(a,b,c,d);
console.log("Merged a,b,c,d:", abcd);
const abd = mergeObjs(a,b,d);
console.log("Merged a,b,d:", abd);
const ae = mergeObjs(a,e);//prop1 from e will overwrite prop1 from a
console.log("Merged a,e:", ae);
_x000D_
_x000D_
_x000D_

To merge an array of objects, a similar method may be applied.

const mergeArrayOfObjs = arr => Object.assign({}, ...arr);

Demo:

_x000D_
_x000D_
const mergeArrayOfObjs = arr => Object.assign({}, ...arr);
const arr = [
  {a: 1, b: 2},
  {c:1, d:3},
  {abcd: [1,2,3,4], d: 4}
];
const merged = mergeArrayOfObjs(arr);
console.log(merged);
_x000D_
_x000D_
_x000D_


function collect(a, b, c){
    var d = {};

    for(p in a){
        d[p] = a[p];
    }
    for(p in b){
        d[p] = b[p];
    }
    for(p in c){
        d[p] = c[p];
    }

    return d;
}

Shallow-cloning (excluding prototype) or merging of objects is now possible using a shorter syntax than Object.assign().

Spread syntax for object literals was introduced in ECMAScript 2018):

const a = { "one": 1, "two": 2 };
const b = { "three": 3 };
const c = { "four": 4, "five": 5 };

const result = {...a, ...b, ...c};
// Object { "one": 1, "two": 2 , "three": 3, "four": 4, "five": 5 }

Spread (...) operator is supported in many modern browsers but not all of them.

So, it is recommend to use a transpiler like Babel to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.

This is the equivalent code Babel will generate for you:

"use strict";

var _extends = Object.assign || function(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i];
    for (var key in source) {
      if (Object.prototype.hasOwnProperty.call(source, key)) {
        target[key] = source[key];
      }
    }
  }
  return target;
};

var a = { "one": 1, "two": 2 };
var b = { "three": 3 };
var c = { "four": 4, "five": 5 };

var result = _extends({}, a, b, c);
// Object { "one": 1, "two": 2 , "three": 3, "four": 4, "five": 5 }

Why should the function be restricted to 3 arguments? Also, check for hasOwnProperty.

function Collect() {
    var o={};
    for(var i=0;i<arguments.length;i++) {
      var arg=arguments[i];
      if(typeof arg != "object") continue;
      for(var p in arg) {
        if(arg.hasOwnProperty(p)) o[p] = arg[p];
      }
    }
    return o;
}

Underscore has few methods to do this;

1. _.extend(destination, *sources)

Copy all of the properties in the source objects over to the destination object, and return the destination object.

_.extend(a, _.extend(b, c));
=> {"one" : 1, "two" : 2, "three" : 3, "four" : 4, "five" : 5 }

Or

_.extend(a, b);
=> {"one" : 1, "two" : 2, "three" : 3}
_.extend(a, c);
=> {"one" : 1, "two" : 2, "three" : 3, "four" : 4, "five" : 5 }

2. _.defaults(object, *defaults)

Fill in undefined properties in object with values from the defaults objects, and return the object.

_.defaults(a, _.defaults(b, c));
=> {"one" : 1, "two" : 2, "three" : 3, "four" : 4, "five" : 5 }

Or

_.defaults(a, b);
=> {"one" : 1, "two" : 2, "three" : 3}
_.defaults(a, c);
=> {"one" : 1, "two" : 2, "three" : 3, "four" : 4, "five" : 5 }

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to object

How to update an "array of objects" with Firestore? how to remove json object key and value.? Cast object to interface in TypeScript Angular 4 default radio button checked by default How to use Object.values with typescript? How to map an array of objects in React How to group an array of objects by key push object into array Add property to an array of objects access key and value of object using *ngFor

Examples related to dictionary

JS map return object python JSON object must be str, bytes or bytearray, not 'dict Python update a key in dict if it doesn't exist How to update the value of a key in a dictionary in Python? How to map an array of objects in React C# Dictionary get item by index Are dictionaries ordered in Python 3.6+? Split / Explode a column of dictionaries into separate columns with pandas Writing a dictionary to a text file? enumerate() for dictionary in python

Examples related to associative-array

How to insert a new key value pair in array in php? Rename a dictionary key How to update specific key's value in an associative array in PHP? Is there a way to create key-value pairs in Bash script? PHP combine two associative arrays into one array Are there dictionaries in php? Display array values in PHP Adding an item to an associative array Extract subset of key-value pairs from Python dictionary object? Java associative-array