【问题标题】:Update Array containing objects using spread operator使用扩展运算符更新包含对象的数组
【发布时间】:2017-11-15 09:17:05
【问题描述】:

我有一个数组,其中包含 javascript / typescript 中的对象。

let array = [{id:1,name:'One'}, {id:2, name:'Two'}, {id:3, name: 'Three'}]

如何更新第二个元素的名称(id 为 2)并使用 javascript spread (...) 运算符将数组复制到新数组?

【问题讨论】:

  • 你想改变对象吗?还是克隆它并更改名称?
  • 我想关闭一个保持现有对象不变的新数组。
  • 为什么不直接阅读the docs?如果你读了它,你会发现你想要的东西是不可能的。扩展运算符不适用于此类数组修改。我建议你改用 Underscore/Lodash 库。
  • 我明白了,您有使用 Loadash 的示例吗?我希望使用类似 [...array.filter(a=>a.id != 2), array.filter(a=>a.id == 2).name='updated name'] 的东西。但是,这会重新排列数组中的元素。

标签: javascript typescript redux


【解决方案1】:

您可以混合使用.map... spread operator

您可以在创建新数组后设置值

let array = [{id:1,name:'One'}, {id:2, name:'Two'}, {id:3, name: 'Three'}];

let array2 = array.map(a => {return {...a}})

array2.find(a => a.id == 2).name = "Not Two";

console.log(array);
console.log(array2);
.as-console-wrapper { max-height: 100% !important; top: 0; }

或者你可以在.map

let array = [{id:1,name:'One'}, {id:2, name:'Two'}, {id:3, name: 'Three'}];

let array2 = array.map(a => {
  var returnValue = {...a};

  if (a.id == 2) {
    returnValue.name = "Not Two";
  }

  return returnValue
})


console.log(array);
console.log(array2);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 这正是我想要的。谢谢。
【解决方案2】:

有几种方法可以做到这一点。我建议使用Array.map

let new_array = array.map(element => element.id == 2 ? {...element, name : 'New Name'} : element);

Object.assign

let new_array = array.map(element => element.id == 2 ? Object.assign({}, element, {name : 'New Name'}) : element);

Map 返回一个新数组,因此您不需要数组扩展运算符。

【讨论】:

  • 它将返回一个新数组,但数组中的对象仍将是对原始数组对象的引用,所以是的,您确实需要扩展运算符。
  • 不使用扩展运算符,或者使用带有空对象作为目标的 Object.assign。例如,let new_array = array.map(e => e.id == 2 ? Object.assign(e, { name: 'New Name' }) : e) 将改变对象
【解决方案3】:

let array = [{id:1,name:'One'}, {id:2, name:'Two'}, {id:3, name: 'Three'}];

let array2 =[...array.slice(0, 0), Object.assign({}, array[0], {
                   name:'new one'  //change any property of idx
            }),...array.slice(0 + 1)]

console.log(array);
console.log(array2);
[...array.slice(0, idx), Object.assign({}, array[idx], {
               x:new_x  //change any property of idx
        }),...array.slice(idx + 1)]

【讨论】:

  • 你能解释一下你在这段代码中做了什么,并在一个工作的 sn-p 中提供这个吗?
  • Javascript 数组和对象是通过引用传递的,这意味着如果您有一个对象 A,并且您执行 B = A。如果您随后对 A 进行修改,B 也将被更新,因为 B参考 A. 这可能会导致跟踪数组和对象时出现一些奇怪的问题。这个例子所做的是创建一个新数组,将原始数组切片到您要修改的索引,然后从您要更改的那个创建一个新对象,加上更改的值,然后切片原始数组的其余部分并添加它在之后。这是一个新的对象数组,而不是引用。
【解决方案4】:

我们可以使用

let array = [{id:1,name:'One'}, {id:2, name:'Two'}, {id:3, name: 'Three'}];
let array2 = [...array]
array2.find(a => a.id == 2).name = "Not Two";
console.log(array2);

【讨论】:

    【解决方案5】:

    您可以简单地使用map() 并在那里更改元素。 这是代码---

    array_copy = array.map((element) => {
      console.log(element.id);
      if (element.id === 2) {
        element.name = "name changed";
      } 
    return element;
    });
    
    console.log(array_copy);
    

    这里主数组也被修改了,因为数组中的元素是对象,即使在新数组中它也引用相同的位置。

    【讨论】:

      【解决方案6】:

      map可以这样操作,不需要spread

      const array = [{id:1,name:'One'}, {id:2, name:'Two'}, {id:3, name: 'Three'}]
      
      const updatedArray = array.map(a => {
         if (a.id == 2) {
            a.name = 'New Name';
         }
         return a;
      });
      

      【讨论】:

        猜你喜欢
        • 2018-09-04
        • 2017-06-13
        • 2017-03-17
        • 2021-12-28
        • 2017-06-12
        • 1970-01-01
        • 2020-04-27
        • 2022-06-28
        相关资源
        最近更新 更多