Reputation: 2198
I have two functions. One is an impure function that simply returns the result of another. I'm confused by the discrepancy in results between two different ways of calling it.
Functions:
function reverseArray(array) {
var newArray = [];
for(i = 0; i < array.length; i++) {
newArray.unshift(array[i]);
}
return newArray;
}
function reverseArrayInPlace(array) {
return reverseArray(array);
}
When I call:
console.log(reverseArrayInPlace(["one", "two"]));
Console shows what I expect, which is: ["two", "one"]
But when I assign the array to a variable, pass it in as an arg, and log to console, like so:
var foo = ["one", "two"];
reverseArrayInPlace(foo);
console.log(foo);
I get ["one", "two"]
Why does the latter situation yield a different result than the former?
Upvotes: 0
Views: 34
Reputation: 62
newArray.unshift(array[i])
prepends passed elements to the front of the array. Note that the list of elements is prepended as a whole, so that the prepended elements stay in the same order. All numerical array keys will be modified to start counting from zero while literal keys won't be touched.
Look this example:
<?php
$queue = array("orange", "banana");
array_unshift($queue, "apple", "raspberry");
print_r($queue);
?>
The above example will output:
Array
(
[0] => apple
[1] => raspberry
[2] => orange
[3] => banana
)
Note that if you pass an array ["something","another"]
, unshift return ["another","something"]
but not with variables.
Upvotes: 1
Reputation: 5755
Because your code is "call by value."
When reverseArrayInPlace is called with the explicit parameter foo, a copy of foo is made for the body of the function. The function isn't altering the original foo.
In order to set foo to the return value of the function, you can write
foo = reverseArrayInPlace(foo);
Upvotes: 1
Reputation: 100630
First code prints result of the function, second code prints argument of function.
To see that behavior is identical :
var foo = ["one", "two"];
console.log(reverseArrayInPlace(foo));
Side notes:
reverseArray
/reverseArrayInPlace
are pure (not changing values/state and return the same result for same input)foo
to change - to achieve that you need to modify array passed in as argument and not create new one.Code showing one way to change array:
function reverseArrayInPlace(array) {
var reversed = reverseArray(array);
for(var i = 0; i < array.length; i++)
{
array[i] = reversed[i];
}
}
var foo = ["one", "two"];
reverseArrayInPlace(foo);
console.log(foo); // ["two", "one"]
Upvotes: 0
Reputation: 850
It is just as simple as you are not changing state in your program but rather just returning a value. So if you want to affect change in foo, you have to set it equal to the result from reverseArrayInPlace
fixed:
var foo = ["one", "two"];
foo = reverseArrayInPlace(foo);
console.log(foo);
Upvotes: 1