42

I have an array containing objects in javascript / typescript.

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

How can I update name of the second element (with id 2) and copy the array to a new array using javascript spread (...) operator?

developer
  • 1,401
  • 4
  • 28
  • 73
  • Do you want to mutate the object? Or clone it and change the name? – Frank Modica Jun 13 '17 at 14:22
  • I want to close to a new array keeping existing object as is. – developer Jun 13 '17 at 14:23
  • Why not just read [the docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)? If you read it you'll see that it's impossible what you want. Spread operator isn't intended for such array modification. I would suggest you to use Underscore/Lodash library instead. – hindmost Jun 13 '17 at 14:25
  • I see, do you have an example of this using Loadash. I was hoping to use something like [...array.filter(a=>a.id != 2), array.filter(a=>a.id == 2).name='updated name']. However, this will rearrange elements in the array. – developer Jun 13 '17 at 14:27

9 Answers9

50

You can use a mix of .map and the ... spread operator

You can set the value after you've created your new array

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

Or you can do it in the .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; }
George
  • 6,630
  • 2
  • 29
  • 36
6

Using Spred Operator, you can update particular array value using following method

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);
Muthu Kumar
  • 420
  • 5
  • 7
4

There are a few ways to do this. I would suggest using Array.map :

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

or with Object.assign :

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

Map returns a new array, so you shouldn't need the array spread operator.

Raviteja
  • 3,399
  • 23
  • 42
  • 69
David
  • 197
  • 7
  • 1
    It will return a new array but the object inside the array will still be a reference to the original array's object, so yes, you do need the spread operator. – George Jun 13 '17 at 14:43
  • Not with the spread operator, or by using Object.assign with an empty object as the target. For example, doing `let new_array = array.map(e => e.id == 2 ? Object.assign(e, { name: 'New Name' }) : e)` will mutate the object – David Feb 01 '18 at 18:14
1

We can use

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);
Shinoy Babu
  • 1,641
  • 2
  • 12
  • 12
1

You can simply use map() and change the element there. here is the code---

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

console.log(array_copy);

Here the main array also gets modified, as elements inside the array are objects and it references to the same location even in the new array.

Arpan Banerjee
  • 826
  • 12
  • 25
1

You can do it like this in map, no need for 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;
});
user1665355
  • 3,324
  • 8
  • 44
  • 84
1

Merging properties from filterQueryParams to selectedLaws (existing solutions did not suit me):

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);
      }
    }
  }
}
Alexander
  • 1,152
  • 1
  • 16
  • 18
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')
maxspan
  • 13,326
  • 15
  • 75
  • 104
-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)]
Shashank Singh
  • 543
  • 8
  • 12
  • 1
    Can you explain what you've done in this code, and provide this in a working snippet? – OliverRadini Sep 21 '18 at 09:39
  • Javascript arrays and objects are passed by reference, meaning if you have an object A, and you do B = A. If you then make a modification to A, B will be updated as well, because B references A. This can lead to some strange issues with keeping track of arrays and objects. What this example does is create a new array, slice the original up to the index you want to modify, then create a new object from the one you want to change, plus the changed value, then slice the rest fo the original array and add it in after. This is a new array of objects, not a reference. – mycroft16 Feb 24 '19 at 17:33