如何合并两个对象的对象值

时间:2019-01-26 07:56:50

标签: javascript object ecmascript-6 lodash

我有两个这样的对象,想要合并它们:

const obj1 = {
  1: { foo: 1 },
  2: { bar: 2, fooBar: 3 },
  3: { fooBar: 3 },
};

const obj2 = {
  1: { foo: 1, bar: 2 },
  2: { bar: 2 },
};

const merged = someMergingMethod(obj1, obj2);

merged === {
  1: { foo: 1, bar: 2 },
  2: { bar: 2, fooBar: 3 },
  3: { fooBar: 3 },
};

我的意思是,如果键重复,我不仅要合并对象,还要合并对象值的属性。 因为只有merged = { ...obj1, ...obj2 };用obj2的属性覆盖了。

最简单的方法是什么?

我可以使用ES2017和其他类似lodash的库。

5 个答案:

答案 0 :(得分:3)

您可以使用传播运算符。

更新:

  

如果obj2具有obj1没有的某些属性?

最初,我写这个答案时假设键的索引像0,1 and so on一样,但是正如您在评论中提到的那样,不是这样,因为您可以构建键的数组并以

的方式对其进行迭代

由@Nick [...Object.keys(obj1), ...Object.keys(obj2)]

在评论中非常简洁地添加

let obj1 = {1: { foo: 1 },2: { bar: 2, fooBar: 3 },3: { fooBar: 3 },};
let obj2 = {1: { foo: 1, bar: 2 },2: { bar: 2 },};

let keys = [...new Set([...Object.keys(obj1),...Object.keys(obj2)])]
let  op = {}
let merged = keys.forEach(key=>{
  op[key] = {
    ...obj1[key],
    ...obj2[key]
  }
})
console.log(op)

答案 1 :(得分:1)

自从您提到您可以使用 lodash ,您就可以像这样使用merge

public void ClearControlValues(Control Container) { try { foreach (Control ctrl in Container.Controls) { if (ctrl.GetType() == typeof(TextBox)) { ((TextBox)ctrl).Text = ""; } if (ctrl.GetType() == typeof(ComboBox)) { ((ComboBox)ctrl).SelectedIndex = -1; } if (ctrl.GetType() == typeof(CheckBox)) { ((CheckBox)ctrl).Checked = false; } if (ctrl.GetType() == typeof(DateTimePicker)) { ((DateTimePicker)ctrl).Text = ""; } if (ctrl.GetType() == typeof(DataGrid)) { ((DateTimePicker)ctrl).Text = ""; } if (ctrl.Controls.Count > 0) { LockControlValues(ctrl); } } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }

获得所需的结果。

请参见下面的工作示例:

ClearControlValues(this);
_.merge(obj1, obj2)

答案 2 :(得分:1)

我确实有您想要的东西。 此函数将遍历每个嵌套对象并将其与另一个对象合并。我只在树下的5个嵌套层中对其进行了测试,但从理论上讲,它应可用于任意数量的嵌套对象,因为它是递归函数。

//this function is similar to object.assign but,
//leaves the keys which are common among both bojects untouched
function merge(object1, object2)
{
    function combine(p, q)
    {
        for(i in q)
            if(!p.hasOwnProperty(i))
                p[i]= q[i];
        return p;
    }
    obj1= Object.assign(combine(obj1, obj2), obj1);//for the first level 
    obj1= Object.assign(traverse(obj1, obj2), obj1);//for subsequent levels down theobjectt tree

//this function traverses each nested boject and combines it with the other object
    function traverse(a, b)
    {
        if(typeof(a) === "object" && typeof(b) === "object")
            for(i in b)
                if(typeof(a[i]) === "object" && typeof(b[i]) === "object")
                    a[i]= Object.assign(traverse(a[i], b[i]), a[i]);
                else
                    Object.assign(combine(a, b), a);
        return a;
    }
    return obj1;
}

console.log(merge(obj1, obj2));

这是一个更复杂的对象合并的可行示例

var obj1 = {
  1: { foo: 1 },
  2: { bar: 2, fooBar: 3 },
  3: { fooBar: 3, boor:{foob: 1, foof: 8} },
  4: {continent: {
  		asia: {country: {india: {capital: "delhi"}, china: {capital: "beiging"}}},
  		europe:{country:{germany: {capital: "berlin"},france: {capital: "paris"}}}
  	},
  	vegtables: {cucumber: 2, carrot: 3, radish: 7}
  }
};

var obj2 = {
  1: { foo: 1, bar: 2 },
  2: { bar: 2 },
  3: {fooBar: 3, boor:{foob: 1, boof: 6}, boob: 9 },
  4: {continent: {
  		northamerica: {country: {mexico: {capital: "mexico city"}, canada: {capital: "ottawa"}},},
  		asia: {country: {Afghanistan : {capital: "Kabul"}}}
  	}
  },
  5: {barf: 42}
};

//this function is similar to object.assign but,
//leaves the keys which are common among both bojects untouched
function merge(object1, object2)
{
	function combine(p, q)
	{
		for(i in q)
			if(!p.hasOwnProperty(i))
				p[i]= q[i];
		return p;
	}
	obj1= Object.assign(combine(obj1, obj2), obj1);//for the first level 
	obj1= Object.assign(traverse(obj1, obj2), obj1);//for subsequent levels down the object tree

//this function traverses each nested boject and combines it with the other object
	function traverse(a, b)
	{
		if(typeof(a) === "object" && typeof(b) === "object")
			for(i in b)
				if(typeof(a[i]) === "object" && typeof(b[i]) === "object")
					a[i]= Object.assign(traverse(a[i], b[i]), a[i]);
				else
			 		Object.assign(combine(a, b), a);
		return a;
	}
	return obj1;
}

console.log(merge(obj1, obj2));

答案 3 :(得分:0)

您可以使用Object.assign并将对象属性分配给空对象。

var a =  {books: 2};
var b = {notebooks: 1};
var c = Object.assign( {}, a, b );
console.log(c);

您可以使用Lodash库中的merge方法。 可以在这里检查: https://www.npmjs.com/package/lodash

答案 4 :(得分:0)

你看起来像这样吗?

我们可以使用这种方式来合并两个对象。

const person = { name: 'David Walsh', gender: 'Male' };
const attributes = { handsomeness: 'Extreme', hair: 'Brown', eyes: 'Blue' };
const summary = {...person, ...attributes};

/ *

Object {
  "eyes": "Blue",
  "gender": "Male",
  "hair": "Brown",
  "handsomeness": "Extreme",
  "name": "David Walsh",
}

* /