0

I'm trying to write a web-based curve fitting program for my students. In order to do this I need to understand how 2D arrays (arrays of arrays) work in javascript, and it is pretty clear that I don't. In the code below, I expect the two loops that write to the console to give the same result, but they don't. The first one gives what I expect. The second one is mysterious to me. It gives the same result as a simple console.log(q);

Just to be clear, the solution provided in Copying array by value in JavaScript does not work. If I create the array c, then create q by

var q = c.slice();

when I compute the inverse of the matrix c, I find that q has also been inverted. I need to have both the inverted and uninverted versions of the matrix handy...

var q = [];
var c = [];
var row = [];

// create the array q
for (i=0; i<4; i++) {
    row.push(0);
}
for (i=0; i<4; i++) {
    q.push(row);
}

// create the array c
c.push([1, 2, 5, 1]);
c.push([3, -4, 3, -2]);
c.push([4, 3, 2, -1]);
c.push([1, -2, -4, -1]);

for (var i=0; i<4; i++) {
    for (var j=0; j<4; j++) {
        q[i][j] = c[i][j];
        console.log(q[i][j]);
    }
}
console.log('-------------------------')
for (var i=0; i<4; i++) {
    for (var j=0; j<4; j++) {
    console.log(q[i][j]);
    }
}
.as-console-wrapper { max-height: 100% !important; top: 0; }

4 Answers4

3

You're initializing every position with the same array row in memory.

An alternative is to initialize with a new array for each iteration.

var q = [];
var c = [];

for (i=0; i<4; i++) {
    q.push(new Array(4).fill(0));
}

// create the array c
c.push([1, 2, 5, 1]);
c.push([3, -4, 3, -2]);
c.push([4, 3, 2, -1]);
c.push([1, -2, -4, -1]);

for (var i=0; i<4; i++) {
    for (var j=0; j<4; j++) {
        q[i][j] = c[i][j];
        console.log(q[i][j]);
    }
}
console.log('-------------------------')
for (var i=0; i<4; i++) {
    for (var j=0; j<4; j++) {
    console.log(q[i][j]);
    }
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ele
  • 33,468
  • 7
  • 37
  • 75
  • Thanks. It's hard to remember that EVERY time you deal with an array object, you are dealing with a reference, and never the values... – Geoff Nunes Mar 22 '18 at 23:57
0

There is no real 2d array in js. 2d just means that the array contains references to other arrays. In your case however, youve got only one "row". And then you put references to that one row a few times into the outer array.

  row = [0, 0, 0, 0]
  q = [row, row, row, row];
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

Check your reference assignments. Note that you've pushed the same row object on to q four times.

smithco
  • 679
  • 5
  • 17
0

Arrays are passed by reference so each time you modify row you are changing same array. You can create shallow copy using slice() method.

var q = [];
var c = [];
var row = [];

// create the array q
for (i = 0; i < 4; i++) {
  row.push(0);
}
for (i = 0; i < 4; i++) {
  q.push(row.slice());
}

// create the array c
c.push([1, 2, 5, 1]);
c.push([3, -4, 3, -2]);
c.push([4, 3, 2, -1]);
c.push([1, -2, -4, -1]);

for (var i = 0; i < 4; i++) {
  for (var j = 0; j < 4; j++) {
    q[i][j] = c[i][j];
  }
}

console.log(JSON.stringify(q))
console.log(JSON.stringify(c))
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176