What’s the best/standard way of merging two associative arrays in JavaScript? Does everyone just do it by rolling their own for
loop?
Now in 2016 I would say the best/standard way is Object.assign()
Pure Javascript. No jQuery is needed.
obj1 = {a: 1, b: 2};
obj2 = {a: 4, c: 110};
obj3 = Object.assign({},obj1, obj2); // Object {a: 4, b: 2, c: 110}
More information, examples and polyfill here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
do you want to overwrite a property if the names are the same but the values are not?
And do you want to permanently change one of the original objects,
or do you want a new merged object returned?
function mergedObject(obj1, obj2, force){
for(var p in obj1) this[p]= obj1[p];
for(var p in obj2){
if(obj2.hasOwnProperty(p)){
if(force || this[p]=== undefined) this[p]= obj2[p];
else{
n= 2;
while(this[p+n]!== undefined)++n;
this[p+n]= obj2[p];
}
}
}
}
This is how Prototype does it:
Object.extend = function(destination, source) {
for (var property in source) {
if (source.hasOwnProperty(property)) {
destination[property] = source[property];
}
}
return destination;
};
called as, for example:
var arr1 = { robert: "bobby", john: "jack" };
var arr2 = { elizabeth: "liz", jennifer: "jen" };
var shortnames = Object.extend(arr1,arr2);
EDIT: added hasOwnProperty() check as correctly pointed out by bucabay in comments
Underscore also has an extend method:
Copy all of the properties in the source objects over to the destination object. It's in-order, so the last source will override properties of the same name in previous arguments.
_.extend(destination, *sources)
_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}
with jquery you can call $.extend
var obj1 = {a: 1, b: 2};
var obj2 = {a: 4, c: 110};
var obj3 = $.extend(obj1, obj2);
obj1 == obj3 == {a: 4, b: 2, c: 110} // Pseudo JS
(assoc. arrays are objects in js)
look here: http://api.jquery.com/jQuery.extend/
edit: Like rymo suggested, it's better to do it this way:
obj3 = $.extend({}, obj1, obj2);
obj3 == {a: 4, b: 2, c: 110}
As here obj1 (and obj2) remain unchanged.
edit2: In 2018 the way to do it is via Object.assign
:
var obj3 = Object.assign({}, obj1, obj2);
obj3 === {a: 4, b: 2, c: 110} // Pseudo JS
If working with ES6 this can be achieved with the Spread Operator:
const obj3 = { ...obj1, ...obj2 };
In 2019 you have 2 good options:
Object assigning [doc]
const result = Object.assign({}, baseObject, updatingObject);
Object spreading [doc]
const result = { ...baseObject, ...updatingObject};
The first one tends to be safer, more standard and polyvalent. A good pros and cons here