2 Different Outputs When Reversing Array

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



2 Different Outputs When Reversing Array



I am learning Javascript on a book and have to practice reversing an array by creating my own reverse function. The array must be reversed without creating a new variable to hold the reversed array. I thought I found a solution, but when I try to output my answer in 2 different ways (see below), I get different outputs:


function reverseArrayInPlace(array)
for (var i = 0; i < array.length; i += 1)
array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));

console.log(array);


var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];



Here are the outputs:


reverseArrayInPlace(array);
console.log(array);
> [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]



When console.log() is used within the function, I get my desired answer.


console.log()



When console.log() is used outside the function, I get the original array with the last element missing. I would like an explanation to this phenomenon.


console.log()





I re-upvoted this to counteract the -1. Not that I think this is a great question, but we are gonna discourage new users like Kevin if we just go around downvoting without providing any explanation.
– Zach Lysobey
Aug 7 at 20:09


-1




4 Answers
4



The array in the function is on a different scope than that at the global / window level -- the global array is never touched; the function changes a local copy of it instead.


array


array



If you didn't pass array as a parameter to the function, then it would act on the now unmasked global array variable:


array


array




function reverseArrayInPlace() // <-- no parameter
for (var i = 0; i < array.length; i += 1)
array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));

console.log(array);


var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
reverseArrayInPlace();
console.log(array);



(...although it is generally bad practice to use globals like that, partly because it's easy to accidentally mask them with local variables just as you did here. A better pattern would be for functions to receive their data as params and return a value, so you can decide, when you call the function, what to assign that returned value to.)



Inside reverseArrayInPlace you are reassigning the array variable, not changing (mutating) it. The array you pass in, therefore, is not changed. The inside console.log sees the new array while the one outside sees the original.


reverseArrayInPlace


array


array



Perhaps you want something like this instead


function reverseArrayInPlace(array)
for (var i = 0; i < array.length; i += 1)
array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));

return array;


var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var newArray = reverseArrayInPlace(array)

console.log(newArray)





Hello Zach, thanks for your answer! I guess the mutation concept was the primary issue here. I'm glad that you have brought this up! I understand my problem in depth now. As for the proposed solution, I do not think it would be appropriate for my case even though it works because the book specifically stated that I change the original array instead of creating a new variable for it.
– Kevin Bie
Aug 7 at 20:24




Just a different approach by using the function stack for storing an item of the array by popping the value, check the length of the array and call the function again with the same object reference and then unshift the temporary stored value.



While working for a small amount of values and because of the limited stack, it is not advisable to use this beside of educational purpose.




function reverseArrayInPlace(array)
var temp = array.pop();
if (array.length)
reverseArrayInPlace(array);

array.unshift(temp);


var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

reverseArrayInPlace(array);

console.log(array);


.as-console-wrapper max-height: 100% !important; top: 0;





Hello Nina, thanks for providing an alternate and unique solution! Would it be possible to clarify what the line array.length && reverseArrayInPlace(array); does? I mainly do not understand the purpose of using the && operator in this case.
– Kevin Bie
Aug 7 at 20:46


array.length && reverseArrayInPlace(array);





it is a logical AND &&, which checks the left side for a truthy value and if not (a falsy value) it checks the other side by calling the function. i changed the code to a user friendly if statement.
– Nina Scholz
Aug 7 at 20:49


&&


if



In the first loop of your for you are calling array.pop() which modifies the array passed as argument, but then you are creating a new array storing it in the same variable, so the reference to the original array is lost, and then in the subsequent loops the modified array is the one being generated inside your function.


for


array.pop()



Look at this code, I added a line to copy the original array, thus not modificating the original passed as argument.




function reverseArrayInPlace(array)
array = array.slice(); //copying the passed array to not change the original
for (var i = 0; i < array.length; i += 1)
array = array.slice(0, i).concat(array.pop()).concat(array.slice(i));

console.log(array);


var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

reverseArrayInPlace(array);
console.log(array);





Hey thanks for addressing the issue with the '10' missing from the original array. So basically, when I create a new reference, let's say var a = b, then the expressing in b is read first, then assigned to the variable a, correct?
– Kevin Bie
Aug 7 at 20:21



var a = b


b


a





@KevinBie Not sure if I understood correctly, in JS when you store an array (or an object) in a variable, what you are actually doing is storing its memory address in the variable and not the array itself. So if you do var a = [1, 2];, a internally will be an address pointing to the [1, 2] array, then if you do var b = a; what you are doing is storing the same address from a into b, so now a and b will be pointing to the same location in memory, if you modify the array in b, the array in a will be changed. Hope this clarifies your issue.
– Alvaro Castro
Aug 8 at 16:03



var a = [1, 2];


a


[1, 2]


var b = a;


a


b


a


b


b


a





@KevinBie What you are trying to do is some book/guide exercise? I might be wrong but you can try the built-in array.reverse() to flip the array.
– Alvaro Castro
Aug 8 at 16:06


array.reverse()






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

Creating a leaderboard in HTML/JS