我有一个对象数组。我想通过某个字段找到它,然后改变它:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundItem = items.find(x => x.id == item.id);
foundItem = item;
我想让它改变原来的对象。怎么做?(我不在乎它是否也会在Lodash中。)
我有一个对象数组。我想通过某个字段找到它,然后改变它:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundItem = items.find(x => x.id == item.id);
foundItem = item;
我想让它改变原来的对象。怎么做?(我不在乎它是否也会在Lodash中。)
当前回答
虽然大多数现有的答案都很好,但我想包括一个使用传统for循环的答案,这里也应该考虑到这一点。OP请求一个ES5/ES6兼容的答案,传统的for循环应用:)
在这种情况下使用数组函数的问题是,它们不会改变对象,但在这种情况下,改变是必要的。使用传统for循环的性能增益只是一个(巨大的)奖励。
const findThis = 2;
const items = [{id:1, ...}, {id:2, ...}, {id:3, ...}];
for (let i = 0, l = items.length; i < l; ++i) {
if (items[i].id === findThis) {
items[i].iAmChanged = true;
break;
}
}
虽然我非常喜欢数组函数,但不要让它们成为你工具箱中的唯一工具。如果目的是改变数组,它们就不是最合适的。
其他回答
你可以使用findIndex来查找对象数组中的索引,并根据需要替换它:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundIndex = items.findIndex(x => x.id == item.id);
items[foundIndex] = item;
这假设了唯一的id。如果你的id是重复的(就像你的例子一样),使用forEach可能会更好:
items.forEach((element, index) => {
if(element.id === item.id) {
items[index] = item;
}
});
我最好的方法是:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
items[items.findIndex(el => el.id === item.id)] = item;
findIndex的引用
如果你不想用new object替换,而是复制item的字段,你可以使用object .assign:
对象分配(项目[项目。findIndex(el => el)id ===项目。
作为.map()的替代:
对象。分配(项目,项目。地图(el => el)id ===项目。id?项目:el)
功能的方法:
不要修改数组,使用一个新的数组,这样就不会产生副作用
const updatedItems = items.map(el => el.id === item.id ? item : el)
Note
如果使用得当,对对象的引用不会丢失,因此您甚至可以使用原始的对象引用,而不是创建新的对象引用。
const myArr = [{ id: 1 }, { id: 2 }, { id: 9 }];
const [a, b, c] = myArr;
// modify original reference will change object in the array
a.color = 'green';
console.log(myArr[0].color); // outputs 'green'
这个问题通常发生在从数据库中消费列表,然后将列表映射到生成HTML内容,这将修改列表的元素,然后我们需要更新列表并将其作为列表发送回数据库。
Good news is, references are kept, so you could organize your code to get advantage of it, and think about a list as an Object with identities for free, which are integers from 0 to length -1. So every time you access any property of your Object, do it as list[i], and you don't lose reference, and original object is changed. Keep in mind that this is useful when your source of truth is only one (the Object created), and your app is always consistently consuming the same Object (not fetching several times from database and assigning it to list along the lifespan of the component).
坏消息是架构是错误的,如果这是您所需要的,您应该通过ids(字典)接收一个对象,例如
{
1232: { id: 1232, ...},
asdf234asf: { id: 'asdf234asf', ...},
...
}
这样,就不用在数组中搜索,这会消耗资源。你“只是通过对象中的键访问”,这是即时的和性能的。
为我工作
let returnPayments = [ ...this.payments ];
returnPayments[this.payments.findIndex(x => x.id == this.payment.id)] = this.payment;
另一种方法是使用拼接。
splice()方法通过删除或替换现有元素和/或在适当位置添加新元素来更改数组的内容。
注意:如果你正在使用响应式框架,它会更新“视图”,你的数组“知道”你已经更新了它。
答:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
let foundIndex = items.findIndex(element => element.id === item.id)
items.splice(foundIndex, 1, item)
如果你只想改变一个项的值,你可以使用find函数:
// Retrieve item and assign ref to updatedItem
let updatedItem = items.find((element) => { return element.id === item.id })
// Modify object property
updatedItem.aProp = ds.aProp
可使用过滤器。
const list = [{id:0}, {id:1}, {id:2}];
let listCopy = [...list];
let filteredDataSource = listCopy.filter((item) => {
if (item.id === 1) {
item.id = 12345;
}
return item;
});
console.log(filteredDataSource);
数组[对象{id: 0},对象{id: 12345},对象{id: 2}]