Search code examples
javascriptarraysspread-syntax

Can the 'spread operator' replace an object with same uuid? Solution: Object.assing()


I was trying to replace a property of an Object in an array with the spread syntax like this:

const origArray = [
  {
    "uuid":"first-team-uuid",
    "name":"Team 1",
    "players": [
      "first-team-uuid"
    ]
  },
  {
    "uuid":"second-team-uuid",
    "name":"Team 2",
    "players":[]
  }
]

const doesNotWork = (prev, index, newName) => [...prev, {...prev[index], name: newName}]

const result1 = doesNotWork(origArray, 0, "Team3")

console.log(result1)

// # I know this works:

const doesWork = (prev, index, newName) => {
  let old = [...prev]
  old.splice(index, 1, {...prev[index], name: newName});
  return old;
}

const result2 = doesWork(origArray, 0, "Team3")

console.log(result2)

I expect reslut1 to be like result2, but I seem to be wrong. I would like to write this in a singe line function and not with the workaround I currently have, if possible.


Solution

  • I can suggest these ways, through a filter, a map and an object.

    But filter way changes the order of elements in array

    const origArray = [
      {"uuid":"c752cf08","name":"Team 1",},
      {"uuid":"d46829db","name":"Team 2",},
      {"uuid":"d46829d0","name":"Team 3",}];
    
    const match = 1;
    const name = 'Team 100';
    
    //------------------------
    const workWithFilter = (prev) =>  
      [...prev.filter((_, i) => i !== match), { ...prev[match], name }];
      
    const result1 = workWithFilter(origArray);
    console.log('workWithFilter:', result1);
    
    //------------------------
    const workWithMap = (prev) => 
      prev.map((v, i) =>  (i === match) ? { ...v, name } : v);
    
    const result3 = workWithMap(origArray);
    console.log('workWithMap:', result3);
    
    //------------------------
    const workWithObject = (prev) => 
      Object.assign([...prev], { [match]: { ...prev[match], name } });
    
    const result4 = workWithObject(origArray);
    console.log('workWithObject:', result4);
    
    //------------------------
    const doesWork = (prev) => {
      let old = [...prev]
      old.splice(match, 1, { ...prev[match], name });
      return old;
    }
    
    const result2 = doesWork(origArray);
    console.log('doesWork:', result2);
    .as-console-wrapper {max-height: 100% !important; top: 0}