我有以下两个对象数组。我想做的是,如果id
属性匹配,则将数组x
项替换为数组y
项。
我可以从一个普通的 for 循环轻松实现这一目标。但我不明白为什么我的 for 循环返回不同的结果。
let x1 = [{
id: '1',
a: 1,
b: 2
}];
let y1 = [{
id: '1',
c: 3,
b: 2
}];
let x2 = [{
id: '1',
a: 1,
b: 2
}];
let y2 = [{
id: '1',
c: 3,
b: 2
}];
let updateX1 = (x, y) => {
for (let itemY of y) {
for (let itemX of x) {
if (itemY.id === itemX.id) {
itemX = itemY;
}
}
}
return x;
}
let updateX2 = (x, y) => {
for (let i = 0; i < y.length; i++) {
for (let j = 0; j < x.length; j++) {
if (y[i].id === x[j].id) {
x[j] = y[i];
}
}
}
return x;
}
console.log(updateX1(x1, y1));
console.log(updateX2(x2, y2));
为什么上述两种方法会得到两种不同的结果?预先感谢!
答案 0 :(得分:5)
本身重新分配变量将永远不会使现有对象发生变异,或者至少不会在非常奇怪的情况下进行变异。当你做
itemX = itemY;
您只是将itemX
变量指向的值更改为itemY
。最初的itemX
以及itemX
所来自的对象都不会更改。为了使对象变异,您必须始终明确地为对象的 property 分配一个新值,例如使用obj.foo
,obj['foo']
或在代码中, x[j] = y[i];
。
答案 1 :(得分:1)
如果您实际上想说的是:
如果id属性匹配,则将数组x项替换为数组y 项目
const x = [
{ id: 1, name: 'should be replaced by y' },
{ id: 2, name: 'not replaced' },
];
const y = [
{ id: 1, name: 'this is from y' },
{ id: 3, name: 'not not used' },
];
const newX = x.map((xItem) => {
const fromY = y.find((yItem) => yItem.id === xItem.id);
return fromY ? fromY : xItem;
});
console.log(newX);
如果要进行突变,则可以使用forEach,因为它更适合副作用
const x = [
{ id: 1, name: 'should be replaced by y' },
{ id: 2, name: 'not replaced' },
];
const y = [
{ id: 1, name: 'this is from y' },
{ id: 3, name: 'not not used' },
];
//mutate x
x.forEach((xItem, index) => {
const fromY = y.find((yItem) => yItem.id === xItem.id);
x[index] = fromY ? fromY : xItem;
});
console.log(x);