修改数组对象中的对象属性

98
var foo = [{ bar: 1, baz: [1,2,3] }, { bar: 2, baz: [4,5,6] }];

var filtered = $.grep(foo, function(v){
    return v.bar === 1;
});

console.log(filtered);

有没有一种方法可以修改某个对象的属性(就像我上面筛选掉的那个)而不需要创建新的数组和/或对象?

期望的结果:[{ bar: 1, baz: [11,22,33] }, { bar: 2, baz: [4,5,6] }]

http://jsfiddle.net/98EsQ/


@squint 我正在寻找一种方法,可以让我“指向”某个对象并允许我修改它(无论是在ES还是jQuery中)。但我想我必须手动使用foreach来实现 :) - Johan
12个回答

83

.map结合展开...)运算符

var result = foo.map(el => el.bar == 1 ? {...el, baz: [11,22,33]} : el);


我无法根据先前的值更新“baz”,只能完全更改属性值。 - Goran_Ilic_Ilke

46
当然,只需更改它:
使用jQuery的$.each
$.each(foo, function() {
    if (this.bar === 1) {
        this.baz[0] = 11;
        this.baz[1] = 22;
        this.baz[2] = 33;
        // Or: `this.baz = [11, 22, 33];`
    }
});

使用ES5的forEach方法:

foo.forEach(function(obj) {
    if (obj.bar === 1) {
        obj.baz[0] = 11;
        obj.baz[1] = 22;
        obj.baz[2] = 33;
        // Or: `obj.baz = [11, 22, 33];`
    }
});

...或者你可以在这个 Stack Overflow 回答中找到其他循环选项


36
你可以使用 find 方法并更改其属性。

let foo = [{ bar: 1, baz: [1,2,3] }, { bar: 2, baz: [4,5,6] }];

let obj = foo.find(f=>f.bar==1);
if(obj)
  obj.baz=[2,3,4];
console.log(foo);


这仅在您知道始终只有一个匹配项时才有用。 - Gie
1
@AdiG 确实。如果您正在查看多个,最好使用 map,就像这个答案中所示。 - Suraj Rao

11

我们也可以使用数组的map函数来实现这一点:

 foo.map((obj) => {
   if(obj.bar == 1){
     obj.baz[0] = 11;
     obj.baz[1] = 22;
     obj.baz[2] = 33;
   }
 })

10

没有jQuery和向后兼容性

for (var i = 0; i < foo.length; i++) {
    if (foo[i].bar === 1) {
        foo[i].baz = [11,12,13];
    }
}

8
    const objArr = [
        {prop1: 'value1', prop2: 'value11'},
        {prop1: 'value2', prop2: 'value22'},
        {prop1: 'value3', prop2: 'option33'},
        {prop1: 'value4', prop2: 'option44'}
    ]

    const newObjArr = objArr.map(obj => {
            if (['value1', 'value2'].includes(obj.prop1)) {
                return {...obj, prop1: 'newValue'}
            }
            return obj
        }
    )
    
    // const responseGotten = [
    //     { prop1: 'newValue', prop2: 'value11' },
    //     { prop1: 'newValue', prop2: 'value22' },
    //     { prop1: 'value3', prop2: 'option33' },
    //     { prop1: 'value4', prop2: 'option44' }
    // ]

4

但在选择任何一种技术之前,请记住每种方法都会面临与性能相关的挑战。

Object iterate For-In, average: ~240 microseconds.

Object iterate Keys For Each, average: ~294 microseconds.

Object iterate Entries For-Of, average: ~535 microseconds.

参考 - 3个你应该停止做的JavaScript性能错误


3
$.each(foo,function(index,value)
{
    if(this.bar==1)
    {
this.baz[0] = 11;
        this.baz[1] = 22;
        this.baz[2] = 33;
    }

});

但是for循环比$.each更快,所以您可以尝试使用它。

for(var i=0; i <foo.length; i++)
{

if(foo[i].bar==1)
{
//change the code
}
}

3

你可以尝试一下:

const tasks = [ { id: 1, done: false }, { id: 2, done: false } ]
const completed_task = { id: 1, done: true }

const markCompleted = (tasks, task) => {
  const index = tasks.findIndex(t => t.id === task.id);
  tasks.splice(index, 1);
  tasks.push(task);
  return tasks;
}

console.log(tasks)
console.log(markCompleted(tasks, completed_task))

编辑

为避免索引变化:

const markCompleted = (tasks, task) => {
      const index = tasks.findIndex(t => t.id === task.id);
      tasks[index] = task;
      return tasks;
    }

2
您可以使用简单的for循环来修改数组。

var foo = [{ bar: 1, baz: [1,2,3] }, { bar: 2, baz: [4,5,6] }];
for(i = 0;i < foo.length;i++){
  //Here your condition for which item you went to edit
    if(foo[i].bar == 1){
    //Here you logic for update property
        foo[i].baz= [1,11,22]
    }
}
console.log(foo);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接