合并对象(关联数组)

在 JavaScript 中合并两个关联数组的最佳/标准方法是什么?难道每个人都只是通过滚动他们自己的 for循环吗?

103688 次浏览
  1. 在 Javascript 中没有 关联数组,有物体
  2. 合并两个对象的唯一方法是 循环访问它们的属性和 将指针复制到它们的值 不是基元类型和值 将原语类型转换为另一个原语类型 例子

Prototype 是这样做的:

Object.extend = function(destination, source) {
for (var property in source) {
if (source.hasOwnProperty(property)) {
destination[property] = source[property];
}
}
return destination;
};

例如:

var arr1 = { robert: "bobby", john: "jack" };
var arr2 = { elizabeth: "liz", jennifer: "jen" };


var shortnames = Object.extend(arr1,arr2);

编辑 : 添加 hasOwnProperty ()检查,正如 Bucabay 在评论中正确指出的那样

如果名称相同但值不相同,是否覆盖属性?

你想永久地改变一个原始对象吗,

还是要返回一个新的合并对象?

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];
}
}
}
}

道场中,2-object/array“ merge”将是 lang.mixin(destination, source)——您也可以将多个源混合到一个目的地,等等——参见 混合函数的引用了解详细信息。

使用 jquery 可以调用 $.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. 数组是 js 中的对象)

看这里: http://api.jquery.com/jQuery.extend/


就像 Rymo 建议的那样,最好这样做:

obj3 = $.extend({}, obj1, obj2);
obj3 == {a: 4, b: 2, c: 110}

因为这里的 objec1(和 objec2)保持不变。


在2018年,做到这一点的方法是通过 Object.assign:

var obj3 = Object.assign({}, obj1, obj2);
obj3 === {a: 4, b: 2, c: 110} // Pseudo JS

如果使用 ES6,这可以通过 传播接线员实现:

const obj3 = { ...obj1, ...obj2 };

雅虎用户界面(YUI)也有一个助手功能:

Http://developer.yahoo.com/yui/examples/yahoo/yahoo_merge.html

YAHOO.namespace('example');


YAHOO.example.set1 = { foo : "foo" };
YAHOO.example.set2 = { foo : "BAR", bar : "bar" };
YAHOO.example.set3 = { foo : "FOO", baz : "BAZ" };


var Ye = YAHOO.example;


var merged = YAHOO.lang.merge(Ye.set1, Ye.set2, Ye.set3);

下划线 还有一个扩展方法:

将源对象中的所有属性复制到 目标对象。它是按顺序的,所以最后一个源将重写 在前面的参数中具有相同名称的属性。

_.extend(destination, *sources)


_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}

简单点。

function mergeArray(array1,array2) {
for(item in array1) {
array2[item] = array1[item];
}
return array2;
}

我需要一个深度对象合并。所以其他的答案对我没什么帮助。我不知道。除非你有一个像我一样的递归数组,否则扩展和 jQuery 扩展都可以做得很好。但也没那么糟糕,你可以在5分钟内编程:

var deep_merge = function (arr1, arr2) {
jQuery.each(arr2, function (index, element) {
if (typeof arr1[index] === "object" && typeof element === "object") {
arr1[index] = deep_merge(arr1[index], element);
} else if (typeof arr1[index] === "array" && typeof element === "array") {
arr1[index] = arr1[index].concat(element);
} else {
arr1[index] = element;
}
});
return arr1;
}

Jquery 有一个用于深度复制的布尔值,你可以这样做:

MergeRecursive = function(arr1, arr2){
$.extend(true, arr1, arr2);
return arr1;
};

还可以编辑此函数以支持 n 个数组合并。

ArrayMergeRecursive = function(){
if(arguments.length < 2){
throw new Error("ArrayMergeRecursive: Please enter two or more objects to merge!");
}


var arr1=arguments[0];
for(var i=0; i<=arguments.length; i++ ){
$.extend(true, arr1, arguments[i]);
}


return arr1;
};

所以现在你可以

var arr1 = {'color': {'mycolor': 'red'}, 3: 5},
arr2 = {4: 10, 'color': {'favorite': 'green', 0: 'blue'}},
arr3 = ['Peter','Jhon','Demosthenes'],
results = ArrayMergeRecursive(arr1, arr2, arr3); // (arr1, arr2 ... arrN)
console.log("Result is:", results);

滚动自己的 扩展/Mixin函数

function extend(objects) {
var args
, first = Array.prototype.slice.call(arguments, 0, 1)[0]
, second;


if (arguments.length > 1) {
second = Array.prototype.splice.call(arguments, 1, 1)[0];
for (var key in second) {
first[key] = second[key];
}
args = Array.prototype.slice.call(arguments, 0);
return extend.apply(this, args);
}


return first;
}

...

var briansDirections = {
step1: 'Remove pastry from wrapper.',
step2: 'Place pastry toaster.',
step3: 'Remove pastry from toaster and enjoy.',
};
extend(briansDirections, { step1: 'Toast Poptarts' }, { step2: 'Go ahead, toast \'em' }, { step3: 'Hey, are you sill reading this???' });

...

这只是递归地扩展对象的 。另外,请注意这个递归函数是 TCO (尾随呼叫优化) ,因为它的返回值是对它自己的最后一次调用。

此外,您可能需要 目标财产。在这种情况下,您可能希望基于 idquantity或其他属性压缩对象。这种方法可能有一本关于它的小书,需要对象并置,并且可能变得非常复杂。我已经为此编写了一个小型库,可根据要求使用。

希望这个能帮上忙!

要在 jQuery 中合并数组,$. merge 怎么样?

var merged = $.merge([{id:3, value:'foo3'}], [{id:1, value:'foo1'}, {id:2, value:'foo2'}]);
merged[0].id == 3;
merged[0].value == 'foo3';
merged[1].id == 1;
merged[1].value == 'foo1';
merged[2].id == 2;
merged[2].value == 'foo2';

现在在2016年,我认为最好的/标准的方法是 Object.sign ()
纯 Javascript,不需要 jQuery。

obj1 = {a: 1, b: 2};
obj2 = {a: 4, c: 110};
obj3 = Object.assign({},obj1, obj2);  // Object {a: 4, b: 2, c: 110}

更多资料、例子及填料在此:
Https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/object/assign

递归解决方案(也扩展对象数组) + 空检查

var addProps = function (original, props) {
if(!props) {
return original;
}
if (Array.isArray(original)) {
original.map(function (e) {
return addProps(e, props)
});
return original;
}
if (!original) {
original = {};
}
for (var property in props) {
if (props.hasOwnProperty(property)) {
original[property] = props[property];
}
}
return original;
};

测试

console.log(addProps([{a: 2}, {z: 'ciao'}], {timestamp: 13}));
console.log(addProps({single: true}, {timestamp: 13}));
console.log(addProps({}, {timestamp: 13}));
console.log(addProps(null, {timestamp: 13}));


[ { a: 2, timestamp: 13 }, { z: 'ciao', timestamp: 13 } ]
{ single: true, timestamp: 13 }
{ timestamp: 13 }
{ timestamp: 13 }

这是最好的解决办法。

obj1.unshift.apply( obj1, obj2 );

此外,obj1可以在循环内部成长,没有任何问题(假设 obj2是动态的)

2019年,你有两个不错的选择:

对象赋值 [ 医生]

const result = Object.assign({}, baseObject, updatingObject);

目标扩散 [ 医生]

const result = { ...baseObject, ...updatingObject};

第一种趋向于更安全,更标准和多价。一个很好的利弊 给你