如何基于属性(而不是索引)合并2个数组

我们知道jQuery.extend(true, obj1, obj2)方法用于将对象的属性从obj2深度复制到obj1。 在数组的情况下,它根据索引复制属性。 但是我需要根据一些属性进行复制(例如我的情况下为id),如下例所示:

 obj1 = [{id:"id1", name:"name1"},{id:"id2", name:"name2"}] obj2 = [{id:"id3", name:"name3"}{id:"id1", name:"name1_modified"}] 

jQuery.extend将返回:

 [{id:"id3", name:"name3"}{id:"id1", name:"name1_modified"}] 

但我需要输出为:

 [{id:"id1", name:"name1_modified"},{id:"id2", name:"name2"}{id:"id3", name:"name3"}] 

有没有任何方法/库来完成这个?

我在处理项目时遇到了同样的问题。 所以我jquery扩展以基于其属性完成数组合并。 如果要基于属性合并数组,请将属性名称作为合并函数中的最后一个参数传递。 我创建了一个jsfiddle ,在浏览器控制台中查看结果。

 function merge() { var options, name, src, copy, copyIsArray, clone, targetKey, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; var currentId = typeof arguments[length - 1] == 'string' ? arguments[length - 1] : null; if (currentId) { length = length - 1; } // Handle a deep copy situation if (typeof target === "boolean") { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep // copy) if (typeof target !== "object" && !jQuery.isFunction(target)) { target = {}; } // extend jQuery itself if only one argument is passed if (length === i) { target = this; --i; } for (; i < length; i++) { // Only deal with non-null/undefined values if ((options = arguments[i]) != null) { // Extend the base object for (name in options) { if (!options.hasOwnProperty(name)) { continue; } copy = options[name]; var mm = undefined, src = undefined; if (currentId && jQuery.isArray(options) && jQuery.isArray(target)) { for (mm = 0; mm < target.length; mm++) { if (currentId && (isSameString(target[mm][currentId], copy[currentId]))) { src = target[mm]; break; } } } else { src = target[name]; } // Prevent never-ending loop if (target === copy) { continue; } targetKey = mm !== undefined ? mm : name; // Recurse if we're merging plain objects or arrays if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) { if (copyIsArray) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them if (currentId) { target[targetKey] = merge(deep, clone, copy, currentId); } else { target[targetKey] = merge(deep, clone, copy); } // Don't bring in undefined values } else if (copy !== undefined) { target[targetKey] = copy; } } } } // Return the modified object return target; }; function isSameString (a , b){ return a && b && String(a).toLowerCase() === String(b).toLowerCase(); } obj1 = [ { id : "id1", name : "name1" }, { id : "id2", name : "name2" } ] obj2 = [ { id : "id3", name : "name3" }, { id : "id1", name : "name1_modified" } ]; console.log(merge(true, obj1, obj2, "id"));​