7

My understandig was that Array.filter creates a clone of the object, but in the example below both type1 and type1a obviously share the some data.

let initial = [
   {id: 1, type: 1, name: "first", count:0},
   {id: 2, type: 2, name: "second", count:0},
   {id: 3, type: 1, name: "third", count:0},
   {id: 4, type: 2, name: "fourth", count:0},
];

let type1 = initial.filter((item)=>item.type===1);
let type1a = initial.filter((item)=>item.type===1);

type1[0].count = 2;

console.log(type1a[0].count);

Results:

Expected result: 0
Got: 2

What am I missing?

I have tried adding the spread operator in both assignemnet but the result is the same :(


Thanks to @Thomas for the answer.

For your reference, the correct code is:

let initial = [
  { id: 1, type: 1, name: "first", count: 0 },
  { id: 2, type: 2, name: "second", count: 0 },
  { id: 3, type: 1, name: "third", count: 0 },
  { id: 4, type: 2, name: "fourth", count: 0 }
];

// let type1 = initial.filter(item => item.type === 1);
let type1 = [];
initial.forEach((item)=>{
  if(item.type === 1)
    type1.push(JSON.parse(JSON.stringify(item))
    )
})

// let type1a = initial.filter(item => item.type === 1);

  let type1a = [];
  initial.forEach((item)=>{
    if(item.type === 1)
      type1a.push(JSON.parse(JSON.stringify(item))
      )
  })

  type1[0].count = 2;

  console.log(type1[0].count);
  console.log(type1a[0].count);
Pepe
  • 431
  • 5
  • 14
  • 7
    `.filter()` makes a new array, but it does not deep-copy the values from the original array. – Pointy Mar 23 '20 at 16:37
  • 1
    I am not sure if I understand correct but it seems to me that type1 and type1a are referencing the same array, – Pepe Mar 23 '20 at 16:38
  • 1
    Array.filter doesn’t clone anything, but it does create a new array. The new array contains the same objects. (I guess you could call `arr.filter(x => true)` a shallow clone of the array.) – Ry- Mar 23 '20 at 16:38
  • It just creates new references to the object VALUE, the value is not cloned. – Sang Dang Mar 23 '20 at 16:38
  • 1
    They are not referencing the same array, as you can demonstrate by logging the result of `type1 === type1a`. – Pointy Mar 23 '20 at 16:38

1 Answers1

14

You get a brand new array, but the array contains references to objects. The references are copied, but not the objects they refer to. This is a so-called "shallow" copy.

To make a "deep" copy that is entirely independent, see this question.

Thomas
  • 174,939
  • 50
  • 355
  • 478
  • Thanks for the answer. Any idea how to do it in one Array.filter statement? – Pepe Mar 23 '20 at 16:40
  • You can't, because `Array.filter` just copies the values (= references) without letting you mutate them. See the linked question on how to subsequently get a deep copy. – Thomas Mar 23 '20 at 16:43