javascriptarraysangularmultidimensional-arrayspread-syntax

Is there an easy way to merge object arrays using javascript ellipsis or similar?


let arr = [
  {id: 1, data: {foo: "bar 1"}},
  {id: 2, data: {foo: "bar 2"}}
];

//In case the ID does not exist just add as a new element on the array
arr = [...arr, {id: 3, data: {foo: "bar 3"}}]
console.log(arr);

//In case the ID exists, replace the data object with the new array provided
arr = [...arr, {id: 2, data: {foo: "new data object"}}]
console.log(arr);

//Expected output:
[
  {id: 1, data: {foo: "bar 1"}},
  {id: 2, data: {foo: "new data object"}},
  {id: 3, data: {foo: "bar 3"}}
]

As you can see in the example bellow, you can only add a new element even thought the ID is the same.

Is there a way to give an object that replaces the object with the same ID in case that it exists, but adds it as a new element to the array if the ID is not found?

I know that I can use the arr.find(i => i.id == newObject.id) to check if that row exists or not and add as a new one or replace depending on the result, but I would like to know if there is a one line solution for this


Solution

  • If you are looking for one line solution using array filter and concat :

    let arr = [
      { id: 1, data: { foo: "bar 1" } },
      { id: 2, data: { foo: "bar 2" } }
    ];
    
    
    let newObj = { id: 2, data: { foo: "new data object" } };
    arr = arr.filter((obj) => obj.id !== newObj.id).concat(newObj);
    console.log(JSON.stringify(arr));
    
    newObj = { id: 3, data: { foo: "bar 3" } };
    
    console.log(JSON.stringify(arr.filter((obj) => obj.id !== newObj.id).concat(newObj)));

    Else go for one line solution like below using Spread operator :

    let arr = [
      { id: 1, data: { foo: "bar 1" } },
      { id: 2, data: { foo: "bar 2" } }
    ];
    
    
    let newObj = { id: 2, data: { foo: "new data object" } };
    arr = [...arr.filter(obj => obj.id !== newObj.id), newObj];
    console.log(JSON.stringify(arr));
    
    
    newObj = { id: 3, data: { foo: "bar 3" } };
    arr = [...arr.filter(obj => obj.id !== newObj.id), newObj];
    
    console.log(JSON.stringify(arr));