使用展开运算符更新包含对象的数组

42

我有一个包含JavaScript / TypeScript对象的数组。

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

如何使用JavaScript扩展(...)操作符更新第二个元素(id为2)的名称并将数组复制到新数组中?


你想要改变对象的值吗?还是复制一份并更改名称? - Frank Modica
我想创建一个新数组,同时保留现有对象。 - developer
为什么不直接阅读文档呢?如果你阅读了它,你会发现你想要的是不可能的。展开运算符并不适用于这种数组修改。我建议你使用Underscore/Lodash库。 - hindmost
我明白了,你能否提供一个使用Loadash的例子呢?我希望使用类似于[...array.filter(a=>a.id != 2), array.filter(a=>a.id == 2).name='updated name']的方式。然而,这种方法会重新排列数组中的元素。 - developer
9个回答

51
你可以使用 .map... 扩展运算符 的组合。
在创建新数组后,您可以设置其值。

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; }


1
这正是我在寻找的。谢谢你。 - developer

6
使用展开运算符,您可以使用以下方法更新特定数组值。

let array = [
  { id: 1, name: "One" },
  { id: 2, name: "Two" },
  { id: 3, name: "Three" },
];
const label = "name";
const newValue = "Two Updated";
// Errow comes if index was string, so make sure it was integer
const index = 1; // second element, 

const updatedArray = [
  ...array.slice(0, index),
  {
    // here update data value
    ...array[index],
    [label]: newValue,
  },
  ...array.slice(index + 1),
];

console.log(updatedArray);


4

有几种方法可以做到这一点。我建议使用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函数返回一个新数组,所以你不需要使用数组展开运算符。


1
它将返回一个新的数组,但数组内部的对象仍然是原始数组对象的引用,因此,是的,您需要使用展开运算符。 - George
不要使用展开运算符或者使用一个空对象作为目标来使用Object.assign。例如,执行let new_array = array.map(e => e.id == 2 ? Object.assign(e, { name: 'New Name' }) : e)会改变对象。 - David

2
我们可以使用

标签


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);

1
filterQueryParams中的属性合并到selectedLaws中(现有解决方案不适合我):
if (this.filterQueryParams && Object.prototype.toString.call(this.filterQueryParams) === '[object Array]') {
  for (const law of this.filterQueryParams) {
    if (law as Laws.LawDetail) {
      const selectedLaw = this.selectedLaws.find(x => x.languageCode === law.languageCode);
      if (selectedLaw) {
        for (const propName of Object.keys(law)) {
          selectedLaw[propName] = law[propName];
        }
      }
      else {
        this.selectedLaws.push(law);
      }
    }
  }
}

1
你可以简单地使用map()并在其中更改元素。 以下是代码---
array_copy = array.map((element) => {
  console.log(element.id);
  if (element.id === 2) {
    element.name = "name changed";
  } 
return element;
});

console.log(array_copy);

在这里,由于数组中的元素是对象并且它们引用相同的位置,因此主数组也会被修改,即使在新数组中也是如此。


1

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;
});

1
import React,{useState} from 'react';


export function App(props) {
  const[myObject,setMyObject] = useState({
    "Name":"",
    "Age":""
  });
  const[myarray, setmyarray] = useState([]);
const addItem =() =>{
  setMyObject({...myObject,"Name":"Da","Age":"20"});
  setmyarray([...myarray, 1]);
};

  console.log(myarray);console.log(myObject);
  return (
    <div className='App'>
      <h1>Hello React.</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={addItem}>Add me</button>
    </div>

  );
}

// Log to console
console.log('Hello console')

-1

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)]

1
你能解释一下这段代码的作用,并提供一个可工作的片段吗? - OliverRadini
JavaScript 数组和对象是按引用传递的,这意味着如果你有一个对象 A,并且你执行 B = A。如果你对 A 进行修改,B 也会被更新,因为 B 引用了 A。这可能会导致一些奇怪的问题,需要跟踪数组和对象。这个例子创建了一个新数组,将原始数组切片到要修改的索引,然后从要更改的对象创建一个新对象,加上更改的值,然后切片剩余的原始数组并在其后添加。这是一个新的对象数组,而不是引用。 - mycroft16

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