babbaggeii
babbaggeii

Reputation: 7737

JavaScript push not pushing correct values

Here's the code:

var stronglyAgree = [];
var agree = [];
var disagree = [];
var stronglyDisagree = [];
var na = [];

for (var i=0; i<survey.questions.length; i++) {

    var tempArray = [];
    tempArray[0] = i*8;
    tempArray[1] = survey.questions[i].answers[0].count;
    stronglyAgree.push(tempArray);
    console.log(tempArray);

    tempArray[1] = survey.questions[i].answers[1].count;
    agree.push(tempArray);

    tempArray[1] = survey.questions[i].answers[2].count;
    disagree.push(tempArray);

    tempArray[1] = survey.questions[i].answers[3].count;
    stronglyDisagree.push(tempArray);

    tempArray[1] = survey.questions[i].answers[4].count;
    na.push(tempArray);

}
console.log(stronglyAgree);

As you can see, I'm logging the tempArray, which is being pushed to stronglyAgree. When it comes to the last question, for example, I get:

`tempArray = [72,1]`

But the last array in stronglyAgree is [72,0], which doesn't seem right to me. What am I doing wrong here?

Upvotes: 1

Views: 315

Answers (5)

T.J. Crowder
T.J. Crowder

Reputation: 1074148

The basic problem is that you're only creating one tempArray on each loop iteration, and modifying its contents. So all of the arrays you're pushing it on get a reference to the same tempArray, with the final set of contents you've assigned to it.

For something this simple, I wouldn't bother using tempArray at all:

for (var i=0; i<survey.questions.length; i++) {
    var i8 = i * 8;

    stronglyAgree.push([
        i8,
        survey.questions[i].answers[0].count
    ]);

    agree.push([
        i8,
        survey.questions[i].answers[1].count
    ]);

    disagree.push([
        i8,
        survey.questions[i].answers[2].count
    ]);

    stronglyDisagree.push([
        i8,
        survey.questions[i].answers[3].count
    ]);

    na.push([
        i8,
        survey.questions[i].answers[4].count
    ]);

}

That's if you really want to push a bunch of arrays into your stronglyAgree arrays and such, which seems a bit odd, especially if the first entry in all of them is i multiplied by 8.

Upvotes: 0

Amadan
Amadan

Reputation: 198324

All of your arrays have the same content: tempArray. You change tempArray's content several times, but as you change it, it changes inside all of the other arrays. You need to clone tempArray each time before the next push so it ceases to share the values; in JavaScript, you can do it with tempArray = tempArray.slice(0).

Upvotes: 0

thefourtheye
thefourtheye

Reputation: 239443

When you assign something to an array, like this

tempArray[1] = ...

you are actually mutating the array object. So, no matter how many times you mutate it, it is the same object.

And when you do,

stronglyAgree.push(tempArray);
...
agree.push(tempArray);
...
disagree.push(tempArray);
...
stronglyDisagree.push(tempArray);
...
na.push(tempArray);

You are pushing a reference to the same array object to all the other array objects. Instead, create a new array object whenever you are pushing, like this

stronglyAgree.push(tempArray.slice());
...
agree.push(tempArray.slice());
...
disagree.push(tempArray.slice());
...
stronglyDisagree.push(tempArray.slice());
...
na.push(tempArray.slice());

Now, a copy of the array is created everytime slice is called and the changes to tempArray will no more affect the arrays in the other arrays.

Note: The array objects created by slice are shallow copied arrays. So, if tempArray has a mutable object and if it is mutated with the sliced object, the changes would still be reflected in other array objects.

Upvotes: 4

jcubic
jcubic

Reputation: 66488

It's because you push reference to tempArray not a copy. try:

stronglyAgree.push(tempArray.slice());

Upvotes: 0

Amir Popovich
Amir Popovich

Reputation: 29836

You are using the same reference and changing it:

var arrA = [];
var arrB = [];
var tempArray = [];
tempArray[0] = 10;
tempArray[1] = 7;
arrA.push(tempArray);
tempArray[1] = 8;
arrB.push(tempArray);
console.log(arrA); // [10,8]
console.log(arrB); // [10,8]

You probably would like to create a different array before you change the value.

You can use Array.prototype.slice() for that or just create an array on the fly.

Upvotes: 0

Related Questions