Please explain this to me. I'm trying to create an array of arrays with a for loop. When it didn't work, I tried simplifying the code to understand what Javascript is doing, but the simple code doesn't make sense either.
function test(){
var sub_array = [];
var super_array =[];
for (var i=1;i<=3;i++){
sub_array.push(i);
super_array.push(sub_array);
}
alert(super_array);
}
I expect to see [1; 1,2; 1,2,3]. Instead I get [1,2,3; 1,2,3; 1,2,3]. I get the same phenomenon if I loop 0-2 and assign by index.
well. You have to understand, that Array, Objects, Functions, etc. are references in javascript (only Numbers(Int,Floats,etc) and Strings are passed "by-value", which means, that the value is copied/duplicated)!
if you have an var a=[];
, und say var b=a
and add b.push("bla")
, then alerting a, will show you the "bla" entry, even though you added it to b.
In other words; a and b is to javascript like a note on the frige from mom saying "the sandwhich on the left is for you." And then you know, that to take the left one and not just any random sandwich from the fridge. She also could have written another note (variable b) on your house' door, so that you knew where to go and look for the sandwich if you are in a hurry.
If she would have stuck a sandwich to the door.. well, that would be ackward. And JS thinks the same about it :)
so the solution to your problem is as fallows;
function test(){
var super_array =[];
for (var i=1;i<=3;i++){
var subarray=[];
for (var u=1;u<=4-i;u++){
sub_array.push(u);
super_array.push(subarray);
}
}
alert(super_array);
}
by redefining the subarray, you create a new reference. So that the variable b (the second note on the hous' door) now points in the direction of a different sandwich - maybe dad's sandwich.
I hope I could help you understand this.
You're always pushing a reference to the same array into your super-array.
To solve that problem, you can use slice() to clone the sub-array before pushing it:
function test() {
var sub_array = [];
var super_array = [];
for (var i = 1; i <= 3; i++) {
sub_array.push(i);
super_array.push(sub_array.slice(0));
}
alert(super_array);
}
EDIT: As Dan D. rightfully points out below, you can also call concat() without arguments instead of slice(0)
. It's faster according to this article (I did not measure it myself):
for (var i = 1; i <= 3; i++) {
sub_array.push(i);
super_array.push(sub_array.concat());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With