我有一个对象数组。我想通过某个字段找到它,然后改变它:

var item = {...}
var items = [{id:2}, {id:2}, {id:2}];

var foundItem = items.find(x => x.id == item.id);
foundItem = item;

我想让它改变原来的对象。怎么做?(我不在乎它是否也会在Lodash中。)


当前回答

使用展开运算符的一行程序。

 const updatedData = originalData.map(x => (x.id === id ? { ...x, updatedField: 1 } : x));

其他回答

你可以使用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;
    }
});

在我的例子中,我想找到一些元素(及其长度),并想在对象本身中添加一个新元素no_of_agents。所以,跟随确实帮助了我

  details.forEach(obj => {
                const length = obj["fleet_ids"].length || 0;
                obj.set("no_of_agents" , length)
            });

以某种方式map()返回其他细节(如'$__':InternalCache, strictMode, shardval等),这是不需要的,

给定一个改变的对象和一个数组:

const item = {...}
let items = [{id:2}, {id:3}, {id:4}];

通过遍历数组,用新对象更新数组:

items = items.map(x => (x.id === item.id) ? item : x)

虽然大多数现有的答案都很好,但我想包括一个使用传统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;
  }
}

虽然我非常喜欢数组函数,但不要让它们成为你工具箱中的唯一工具。如果目的是改变数组,它们就不是最合适的。

使用展开运算符的一行程序。

 const updatedData = originalData.map(x => (x.id === id ? { ...x, updatedField: 1 } : x));