我需要在一个将被大量使用的代码路径中合并两个对象。代码有效,但我担心它的速度不够优化,我正在寻找任何改进/替换我想出的建议。我最初开始在这个问题的最后处理一个例子:How can I merge properties of two JavaScript objects dynamically?。该解决方案适用于简单对象。但是,我的需求有一个扭曲,这是性能问题的来源。我需要能够支持数组
我不需要函数/方法克隆,我不关心hasOwnProperty,因为对象在合并后会返回JSON字符串。
任何建议都可以帮助我从表演中获取最后一次表演。非常感谢。
var utils = require("util");
function mergeObjs(def, obj) {
if (typeof obj == 'undefined') {
return def;
} else if (typeof def == 'undefined') {
return obj;
}
for (var i in obj) {
// if its an object
if (obj[i] != null && obj[i].constructor == Object)
{
def[i] = mergeObjs(def[i], obj[i]);
}
// if its an array, simple values need to be joined. Object values need to be remerged.
else if(obj[i] != null && utils.isArray(obj[i]) && obj[i].length > 0)
{
// test to see if the first element is an object or not so we know the type of array we're dealing with.
if(obj[i][0].constructor == Object)
{
var newobjs = [];
// create an index of all the existing object IDs for quick access. There is no way to know how many items will be in the arrays.
var objids = {}
for(var x= 0, l= def[i].length ; x < l; x++ )
{
objids[def[i][x].id] = x;
}
// now walk through the objects in the new array
// if the ID exists, then merge the objects.
// if the ID does not exist, push to the end of the def array
for(var x= 0, l= obj[i].length; x < l; x++)
{
var newobj = obj[i][x];
if(objids[newobj.id] !== undefined)
{
def[i][x] = mergeObjs(def[i][x],newobj);
}
else {
newobjs.push(newobj);
}
}
for(var x= 0, l = newobjs.length; x<l; x++) {
def[i].push(newobjs[x]);
}
}
else {
for(var x=0; x < obj[i].length; x++)
{
var idxObj = obj[i][x];
if(def[i].indexOf(idxObj) === -1) {
def[i].push(idxObj);
}
}
}
}
else
{
def[i] = obj[i];
}
}
return def;}
要合并的对象样本:
var obj1 = {
"name" : "myname",
"status" : 0,
"profile": { "sex":"m", "isactive" : true},
"strarr":["one", "three"],
"objarray": [
{
"id": 1,
"email": "a1@me.com",
"isactive":true
},
{
"id": 2,
"email": "a2@me.com",
"isactive":false
}
]
};
var obj2 = {
"name" : "myname",
"status" : 1,
"newfield": 1,
"profile": { "isactive" : false, "city": "new York"},
"strarr":["two"],
"objarray": [
{
"id": 1,
"isactive":false
},
{
"id": 2,
"email": "a2modified@me.com"
},
{
"id": 3,
"email": "a3new@me.com",
"isactive" : true
}
]
};
合并后,这个console.log(mergeObjs(obj1,obj2))应该产生这个:
{ name: 'myname',
status: 1,
profile: { sex: 'm', isactive: false, city: 'new York' },
strarr: [ 'one', 'three', 'two' ],
objarray:
[ { id: 1, email: 'a1@me.com', isactive: false },
{ id: 2, email: 'a2modified@me.com', isactive: false },
{ id: 3, email: 'a3new@me.com', isactive: true } ],
newfield: 1 }
答案 0 :(得分:3)
我会查看:https://github.com/bestiejs/lodash
_.merge
不在“优化”功能列表中,但这是经过测试的战斗,战斗硬化。他还有一个性能套件,可以询问您如何为perf套件做出贡献,以便了解merge
实现。
https://github.com/bestiejs/lodash/blob/master/lodash.js#L1677-1738
编辑:顺便说一句,我不会过早地优化。我会在你的用例中看到这实际上是否存在问题,然后继续查看实际数据。我会看一下像:https://github.com/felixge/faster-than-c
基本原则:
他对每一个都有提示。
答案 1 :(得分:1)
如果你不使用Lo-Dash,只想要一个工具合并两个对象,包括它们的数组,请使用deepmerge:https://github.com/nrf110/deepmerge
npm install deepmerge