timonippon
timonippon

Reputation: 335

Push() with Arrays of Arrays in Javascript

I am trying to build an 'array of arrays' (think of a table with columns and rows). I have code that loops through each 'row', and builds an array of 'columns' that it then pushes onto the array of rows:

var myRows = [];  // array of 'column' arrays
var myCols = [];  // 'buffer' for each column

for (r=4; r>=0; r--) {
   myCols.length = 0; 
  for (c=0; c<10; c++) {
   myCols.push("row: " + r +", col: " + c);
  }
  myRows.push(myCols);
}
console.log(myRows);

What I would expect from console.log(myRows) is something like this:

[Array[10], Array[10], Array[10], Array[10], Array[10]]
0: Array[10]
0: "row: 0, col: 0"
1: "row: 0, col: 1"
2: "row: 0, col: 2"
3: "row: 0, col: 3"
4: "row: 0, col: 4"
5: "row: 0, col: 5"
6: "row: 0, col: 6"
7: "row: 0, col: 7"
8: "row: 0, col: 8"
9: "row: 0, col: 9"
length: 10
__proto__: Array[0]
1: Array[10]
0: "row: 1, col: 0"
1: "row: 1, col: 1"
2: "row: 1, col: 2"
3: "row: 1, col: 3"
4: "row: 1, col: 4"
5: "row: 1, col: 5"
6: "row: 1, col: 6"
7: "row: 1, col: 7"
8: "row: 1, col: 8"
9: "row: 1, col: 9"
length: 10
...

However, what instead is logged (in Chrome) shows the row as being '0' for each iteration. Not only that, if I change the iteration rules to not go to 0, it shows whichever the last 'row' would be for all sub arrays of the 'myRows' set of arrays.

Really scratching my head at this one, is there something about the push() method that I'm not understanding?

Upvotes: 2

Views: 844

Answers (4)

nelsonomuto
nelsonomuto

Reputation: 63

You are experiencing this issue because javascript arrays are stored by reference. You are not creating new columns in the outer loop but instead overriding the existing columns and only pushing a new reference to the same columns array into the rows array. Essentially your rows array is an array of 5 references to the same columns array.

To overcome this you must create a new myCols array in the outer loop as such:

var myRows = [];  // array of 'column' arrays

for (r=4; r>=0; r--) {
    var myCols = [];  // 'buffer' for each column
    for (c=0; c<10; c++) {
        myCols.push("row: " + r +", col: " + c);
}
myRows.push(myCols);
}
console.log(myRows);

Upvotes: 0

Farmer Joe
Farmer Joe

Reputation: 6070

You are repeatedly adding the same object over and over for each column. You need to create a new Array on each pass:

var myCols = [];
for (r=4; r>=0; r--) {
    myCols = new Array(); // or temp = [];
    for (c=0; c<10; c++) {
        myCols.push("row: " + r +", col: " + c);
    }
    myRows.push(myCols);
}

Upvotes: 0

Quentin
Quentin

Reputation: 943142

The value of myCols is a reference to an array.

myRows.push(myCols); puts that value into the array referenced by myRows.

In your code, that is always the same array.

myCols.length = 0; removes the contents of that array.


You need to create a new array each time you go around the loop.

Replace myCols.length = 0; with myCols = [];

Upvotes: 1

Barmar
Barmar

Reputation: 780724

You need to create a new cols array each time through the outer loop. You're using the same cols array for each row, and modifying it in place, because myRows.push(myCols) pushes a reference to that array, it doesn't make a copy.

Change:

myCols.length = 0;

to:

myCols = [];

Upvotes: 2

Related Questions