Jannis
Jannis

Reputation: 41

How to prevent an array from updating in a for-loop?

There is an outer array containing many other arrays. I generate the inner arrays an push them to the outer one.

for (i = 0; i < 12; i++) {
        if (i == 0) {
            var p = [];
            for (n = 0; n < 4; n++) {
                p.push(n);
            }
        } else {
            s = i % (3);
            var b = p[s+1];
            p[s+1] = p[s];
            p[s] = b;
        }
        console.log(p);
    }
/*OUTPUT:
Array(4) [ 0, 1, 2, 3 ]
tsp.js:45:17
Array(4) [ 0, 2, 1, 3 ]
tsp.js:45:17
Array(4) [ 0, 2, 3, 1 ]
tsp.js:45:17
Array(4) [ 2, 0, 3, 1 ]
tsp.js:45:17
Array(4) [ 2, 3, 0, 1 ]
tsp.js:45:17
Array(4) [ 2, 3, 1, 0 ]
tsp.js:45:17
Array(4) [ 3, 2, 1, 0 ]
tsp.js:45:17
Array(4) [ 3, 1, 2, 0 ]
tsp.js:45:17
Array(4) [ 3, 1, 0, 2 ]
tsp.js:45:17
Array(4) [ 1, 3, 0, 2 ]
tsp.js:45:17
Array(4) [ 1, 0, 3, 2 ]
tsp.js:45:17
Array(4) [ 1, 0, 2, 3 ]
*/

This code outputs as expected a lot of different arrays. But this one outputs one array containing the same array over and over again:

o = [];
   for (i = 0; i < 12; i++) {
        if (i == 0) {
            var p = [];
            for (n = 0; n < 4; n++) {
                p.push(n);
            }
        } else {
            s = i % (3);
            var b = p[s+1];
            p[s+1] = p[s];
            p[s] = b;
        }
        o.push(p);
    }
    console.log(o);
/*
OUTPUT:
(12) […]
0: Array(4) [ 1, 0, 2, … ]
1: Array(4) [ 1, 0, 2, … ]
2: Array(4) [ 1, 0, 2, … ]
3: Array(4) [ 1, 0, 2, … ]
4: Array(4) [ 1, 0, 2, … ]
5: Array(4) [ 1, 0, 2, … ]
6: Array(4) [ 1, 0, 2, … ]
7: Array(4) [ 1, 0, 2, … ]
8: Array(4) [ 1, 0, 2, … ]
9: Array(4) [ 1, 0, 2, … ]
10: Array(4) [ 1, 0, 2, … ]
11: Array(4) [ 1, 0, 2, … ]
length: 12
<prototype>: Array []
tsp.js:47:13

*/

I expected that the second code outputs all the different arrays from the for loop packed in one array, but it doesn't.

Upvotes: 0

Views: 612

Answers (3)

Nick Parsons
Nick Parsons

Reputation: 50674

When you do o.push(p); you're pushing a reference of p into your array. This means at each iteration of your loop when you modify the elements in p, the elements at your reference change, thus changing the array within your o array.

Thus, you need to make unique references to your p arrays before pushing them into your o array. One way to do this is using .slice() to make a copy of your array like so:

var o = [];
for (var i = 0; i < 12; i++) {
  if (i == 0) {
    var p = [];
    for (var n = 0; n < 4; n++) {
      p.push(n);
    }
  } else {
    var s = i % (3);
    var b = p[s + 1];
    p[s + 1] = p[s];
    p[s] = b;
  }
  o.push(p.slice()); // copy the elements in p to a new array, such that the array is now it's own unique reference in memory
}
console.log(o);

Upvotes: 2

lub0v
lub0v

Reputation: 949

  1. You're declaring var p = []; inside the loop which seems to be working because it is a javascript, but very confusing. Move it to the upper lever near the o = [];
  2. the problem you're facing is because you're pushing the reference to an array and not just values. You need to copy values to a new array before doing a o.push();

        var o = [];
        var p = [];
        for (i = 0; i < 12; i++) {
            if (i == 0) {
                for (n = 0; n < 4; n++) {
                    p.push(n);
                }
            } else {
                s = i % (3);
                var b = p[s + 1];
                p[s + 1] = p[s];
                p[s] = b;
            }
            var copy = [];
            for (j = 0; j < p.length; j++) {
                copy.push(p[j]);
            }
            o.push(copy);
        }
        console.log(o);

Upvotes: 0

zakum1
zakum1

Reputation: 1112

One problem with both examples, is that you declare p in the if branch, but reference it in the else branch and in the enclosing scope.

Try moving it to the start of the function:

for (i = 0; i < 12; i++) {
  var p = [];
  if (i == 0) {

or

var p = [];
for (i = 0; i < 12; i++) {
  if (i == 0) {

Depending on which meets your requirements

Upvotes: 1

Related Questions