ruggero
ruggero

Reputation: 35

javascript array seems to change my itself

I'm working with P5.js and try to save some values in an array and than creating a copy of this array to manipulate. Unfortunately It happens that when I manipulate the second array, also the original one changes, and I can't figure out why.

var particels = []
var particelsCopy = []

function calcInitialPositions(){

  for (var i = 0; i < pixels.length; i+=4) {
    if (pixels[i] == 0){
      var x_ = i  % width
      var y_ = i / width / 2
      var coords_ = {x : x_ , y : y_}
      particels.push(coords_)
    }
  };
}

function setup() {  
  loadPixels()
  calcInitialPositions();
  particelsCopy = particels
}

function draw() {
  for (var i = 0; i < particelsCopy.length; i++) {
    particelsCopy[0].x = 99
  };
  console.log(particel[0].x)
}

Console prints 99

Upvotes: 0

Views: 140

Answers (3)

Steven Spungin
Steven Spungin

Reputation: 29109

The line:

particelsCopy = particels

makes a copy of the array reference, not the elements in the array.

You need to allocate a new array object, then copy the elements. If the elements are objects, you will have to make a shallow (or deep) copy of them as well. This solution uses Object.assign() to make a shallow copy.

particelsCopy = [] // already done previously
for (var i=0; i<particels.length; i++){
   particelsCopy[i] = Object.assign({}, particels[i]};
}

Upvotes: 0

serakfalcon
serakfalcon

Reputation: 3531

The = operator in Javascript assigns Objects, which includes arrays, by reference not by value. So the line:

particelsCopy = particels

is redefining particelsCopy to be an alias of particels.... after that point they are the same array. You need to copy the array by value like:

particelsCopy = particels.slice();

Note this is only a shallow copy, if the array contains objects or arrays they will be copied by reference, you will have to repeat this on child items (e.g. coords_ object, though for objects the pattern is copy = Object.assign({},original);).

To deep copy everything by value, you have to do this for every child level of object/arrays. Many libraries like jQuery have ready-built functions to help this.

Upvotes: 1

Zohaib Ijaz
Zohaib Ijaz

Reputation: 22885

You can use destructuring to copy objects in an array

particelsCopy = particels.map(obj => ({...obj}));

Upvotes: 0

Related Questions