3d0
3d0

Reputation: 23

Strange issue in simple Javascript code, non-empty array parameter reaches function empty

I've been practising JS/ECMAScript lately with examples that I find on the net and while trying one about reversing arrays, I've hit a really strange problem. The code that I put below is complete but half-working.

"use strict";

function reverseArray(theArray){
  let tempArray = [];

  if(theArray && theArray.length > 0){
    console.log('Here works!');
    while(theArray.length > 0){
      tempArray.unshift(theArray.shift());
    }
  }

  return tempArray;
}

function reverseArrayInPlace(theArray){
  console.log(theArray);
  if(theArray && theArray.length > 0){
    console.log('Should go through here!');
    for(let i = 0; i < Math.floor(theArray.length/2); i++){
      let temp = theArray[i];
      theArray[i] = theArray[theArray.length - 1 - i];
      theArray[theArray.length -1 - i] = temp;
    }
  }

  return theArray;
}

let firstSacrifice = ['I','n','v','e','r','t','M','E'];
let secondSacrifice = ['I','n','v','e','r','t','M','E','A','g','a','i','N'];

console.log(firstSacrifice);
console.log('InvertME >>', reverseArray(firstSacrifice));
console.log('InvertME >>', reverseArrayInPlace(firstSacrifice));
console.log('\n');
console.log(secondSacrifice);
console.log('InvertMEAgaiN >>', reverseArray(secondSacrifice));
console.log('InvertMEAgaiN >>', reverseArrayInPlace(secondSacrifice));

The first function, reverseArray, works as expected: it copies the given array into another. The problem comes with the second function, reverseArrayInPlace. In theory, it should do the reversal in the same given array it receives but, strangely, the parameter theArray reaches that function empty []. Therefore, no reversal done with that function at all.

I'm testing the code on a shell with node (v6.10), but in this case I also executed it in the consoles of firefox, chrome and edge with the very same result. For some reason that I cannot fathom (and as usual with this kind of silly errors, I've been trying for a good few hours), the parameter theArray is empty on arrival and, of course, no errors or warnings are given at all.

By the way, I found the exercise proposed in this tutorial about Javascript. I know it's a bit old (and yes, I've already read the docs about JS on MDN) but the exercises proposed there are interesting enough for practice's sake.

Oh, and click here if you want to fiddle with this code, but remember to open the console to see the log entries!

Thanks!

Upvotes: 0

Views: 307

Answers (3)

ibrahim mahrir
ibrahim mahrir

Reputation: 31682

Arrays (and all other javascript objects) are passed by their references not by their values. So in the first call the array is emptied so the next call will recieve an empty array! Thus in those function you should not alter the array passed as parametter. Try this alternative:

function reverseArray(theArray){
  let tempArray = [];

  if(theArray){
    let n = theArray.length;          // use a local variable to tell which item from the array to move
    while(n){                         // while there is still items in theArray to move
      tempArray.push(theArray[--n]);  // decrement n and add its corresponding value to tempArray (here theArray is not altered at all)
    }
  }

  return tempArray;
}

Upvotes: 0

slebetman
slebetman

Reputation: 113866

The problem is this:

tempArray.unshift(theArray.shift());

Specifically:

theArray.shift();

The .shift() method modifies the array in-place by removing the element shifted from the array. So after calling reverseArray() the original array would be empty.

Alternatively the real bug could be with the function name. It should not be called reverseArray but should instead be called returnNewReversedArrayAndEmptyArray.

Upvotes: 0

Bergi
Bergi

Reputation: 664406

The first function, reverseArray, works as expected: it copies the given array into another.

No, it does not. Instead of copying the elements, it moves them - which is surely not what you intended. Calling shift upon the array will empty it - you even do that explicitly while (theArray.length > 0) - i.e. until its length is 0!

To copy the array, you would use something like

function reverseArray(theArray){
  let tempArray = [];
  for (var i=theArray.length; i--; )
      tempArray.push(theArray[i]);
  return tempArray;
}

(though there are many other ways to do it, e.g. return theArray.slice().reverse() using builtins)

Upvotes: 1

Related Questions