calyxofheld
calyxofheld

Reputation: 2198

returning result of one function inside another yields incorrect result

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

Answers (4)

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

La-comadreja
La-comadreja

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

Alexei Levenkov
Alexei Levenkov

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:

  • both functions reverseArray/reverseArrayInPlace are pure (not changing values/state and return the same result for same input)
  • based on function name it looks like you expect 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

Andrew Malta
Andrew Malta

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

Related Questions