0

Sorry I'm new to node js. If you look at the ListComp array it has changed after the while loop. Could someone explain what is wrong with this code?

function FormGrp() {
 var ListOne = [];
 var ListTwo = [];
 var count = 0;
 var Control;
 var graph = [];
 var ListComp = [[59],[73,41],[52,40,9],[26,53,6,34],[10,51,87,86,81]];

 Control = 4;
 console.log(ListComp);

 while(Control != 0){
       ListOne = ListComp[count];
       ListTwo = ListComp[count+1];
       for(var i=0; i<ListOne.length; i++){
            for(var j=0; j<ListTwo.length; j++){
              if(j === 2){
                  ListTwo.shift();
                  break;
                }
                graph.push([ListOne[i],ListTwo[j]]);
            }
       }
       count++;
       Control--;
 }
    console.log('\n',ListComp);
}

In the two console outputs the values ​​were different, but I did not use any mocking method in the ListComp array, how could it have been changed?

enter image description here

Chance
  • 1,497
  • 2
  • 15
  • 25
  • ListTwo = ListComp[count+1]; Index out of bounds in the first loop iteration. Initialize **Control** variable. Control = 3; – tdjprog Apr 02 '18 at 01:12
  • `ListOne` and `ListTwo` are referring to 2 elements of ListComp. Because they are Array, when you modify them, the original items are also being affected. Let's do a smaller example: ``` a = [[1], [2], [3]] console.log(a) b = a[1] // [2] b.push(4) // [2, 4] console.log(a) ``` – Dong Nguyen Apr 02 '18 at 01:15
  • @DongNguyen But I do not want to change the matrix, how can I avoid changing the matrix without reference? – Chance Apr 02 '18 at 01:39
  • @AndersonMendes: the simplest way is use three dots in ES6: ``` ListOne = [...ListComp[count]]; ListTwo = [...ListComp[count+1]]; ``` In short, by using three dots, you created an immutable array from given array. – Dong Nguyen Apr 02 '18 at 02:41

1 Answers1

0

It changes because objects are copied by reference, and in Javascript an Array is an object. So, if you change the copy the original one is going to be affected as well.

Take into account that ListComp is an array of arrays, which means that if you copy one of those arrays in ListComp you are copying them by reference. For example in this line:

ListOne = ListComp[count]

In the first iteration you are copying the array [59] by reference to the array ListOne.

Let's see an example with just a simple array:

const arr = [1, 2, 3];
const arrCopy = arr;
arrCopy.push(4)
console.log(arr); // [1, 2, 3, 4]
console.log(arrCopy); // [1, 2, 3, 4]

A fast way to solve it is using, for example, Array#slice() to clone the arrays:

 ListOne = ListComp[count].slice();
 ListTwo = ListComp[count+1].slice();

But maybe structuring your code in a way you don't need to create clones could be better though.

Antonio Val
  • 3,200
  • 1
  • 14
  • 27