Javascript:在不改变数组的情况下更改数组中元素的值
Javascript: Change the value of an element in an array without mutating the array
假设我有一个数组,格式如下:
const array = [{id: 1, title: "this"}, {id: 2, title: "that"}];
我想更改给定 object 中一个元素的值。因此,例如,我的输出是这样的:
[{id: 1, title: "this"}, {id: 2, title: "foo foo foo"}];
我正在将具有两个属性的 object 传递给我的函数。第一个属性是我要修改的object的id,第二个属性是new标题:
[2, "foo foo foo"]
我可以使用以下代码找到正确 object 的索引:
index = array.findIndex(item => item.id === arr[0]);
但我不知道如何更改元素并将其替换为我的新标题 (arr[1])。
我想更改第二个 object 中的标题元素而不改变数组 。非常感谢任何建议。
编辑:对于 "without mutating the array" 的混淆,我们深表歉意。我的意思是我不希望 returned 数组只是原始数组的一个突变,而是一个新数组。也许 "without mutating the state" 会是更好的选择。
例如,如果我要 return 数组,如下所示:
return [...状态]
这将给我一个新数组(尽管没有更改)而不改变原始数组。
const array = [{
id: 1,
title: "this"
}, {
id: 2,
title: "that"
}];
function replaceTitle(oldArray, [itemId, newTitle]) {
let newArray = JSON.parse(JSON.stringify(oldArray));
(newArray.find(({id}) => id === itemId) || {}).title = newTitle;
return newArray;
}
const newArray = replaceTitle(array, [2, 'foo foo foo']);
console.log('ORIGINAL', array);
console.log('UPDATED', newArray);
您没有改变数组。您正在更改数组中包含的对象的 属性。该数组存储对您的对象的引用。
如果要更改数组中的对象但仍想保留原始对象,则必须深度复制存储在数组中的所有对象。
你不能真正改变一个对象而不是......好吧改变它。您需要对象的副本。假设复制数组不会花费太多,您可以执行以下操作:
const arr = [{id: 1, title: "this"}, {id: 2, title: "that"}];
const a2 = arr.map(i => i.id == 2 ? Object.assign({}, i, {title: 'foo foo foo'}): i)
console.log("original: ", arr)
console.log("with changes: ", a2)
在这种情况下,您复制的是原始对象,但已更改的对象除外,它会获得包含更改的副本并单独保留原始对象。
您可以使用 Array.map
函数遍历数组和 return 新数组。在 map
函数中,检查 id
是否与 id passed in the arguments of the function
相同。如果条件为真,则使用 ...(spread operators)
.
创建一个新对象
const arr = [{id: 1, title: "this"}, {id: 2, title: "that"}];
var change = (id, title) => {
return arr.map(obj => {
if (obj.id === id) {
return {...obj, title};
}
return obj;
});
}
var arr2 = change(2, "foo foo foo");
console.log("original: ", arr);
console.log("with changes: ", arr2);
假设我有一个数组,格式如下:
const array = [{id: 1, title: "this"}, {id: 2, title: "that"}];
我想更改给定 object 中一个元素的值。因此,例如,我的输出是这样的:
[{id: 1, title: "this"}, {id: 2, title: "foo foo foo"}];
我正在将具有两个属性的 object 传递给我的函数。第一个属性是我要修改的object的id,第二个属性是new标题:
[2, "foo foo foo"]
我可以使用以下代码找到正确 object 的索引:
index = array.findIndex(item => item.id === arr[0]);
但我不知道如何更改元素并将其替换为我的新标题 (arr[1])。
我想更改第二个 object 中的标题元素而不改变数组 。非常感谢任何建议。
编辑:对于 "without mutating the array" 的混淆,我们深表歉意。我的意思是我不希望 returned 数组只是原始数组的一个突变,而是一个新数组。也许 "without mutating the state" 会是更好的选择。
例如,如果我要 return 数组,如下所示: return [...状态] 这将给我一个新数组(尽管没有更改)而不改变原始数组。
const array = [{
id: 1,
title: "this"
}, {
id: 2,
title: "that"
}];
function replaceTitle(oldArray, [itemId, newTitle]) {
let newArray = JSON.parse(JSON.stringify(oldArray));
(newArray.find(({id}) => id === itemId) || {}).title = newTitle;
return newArray;
}
const newArray = replaceTitle(array, [2, 'foo foo foo']);
console.log('ORIGINAL', array);
console.log('UPDATED', newArray);
您没有改变数组。您正在更改数组中包含的对象的 属性。该数组存储对您的对象的引用。
如果要更改数组中的对象但仍想保留原始对象,则必须深度复制存储在数组中的所有对象。
你不能真正改变一个对象而不是......好吧改变它。您需要对象的副本。假设复制数组不会花费太多,您可以执行以下操作:
const arr = [{id: 1, title: "this"}, {id: 2, title: "that"}];
const a2 = arr.map(i => i.id == 2 ? Object.assign({}, i, {title: 'foo foo foo'}): i)
console.log("original: ", arr)
console.log("with changes: ", a2)
在这种情况下,您复制的是原始对象,但已更改的对象除外,它会获得包含更改的副本并单独保留原始对象。
您可以使用 Array.map
函数遍历数组和 return 新数组。在 map
函数中,检查 id
是否与 id passed in the arguments of the function
相同。如果条件为真,则使用 ...(spread operators)
.
const arr = [{id: 1, title: "this"}, {id: 2, title: "that"}];
var change = (id, title) => {
return arr.map(obj => {
if (obj.id === id) {
return {...obj, title};
}
return obj;
});
}
var arr2 = change(2, "foo foo foo");
console.log("original: ", arr);
console.log("with changes: ", arr2);