1

Can anyone show me where I'm going wrong with this function on reversing arrays? It's an exercise from the book Eloquent JavaScript.

I've checked my variables through the console and the loop seems to be working but at the end the array indexes don't seem to get overwritten and I don't understand why!

The answer I'm looking for is:

var arrayValue = [1, 2, 3, 4, 5];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
// → [5, 4, 3, 2, 1]

"use strict";
var sampleArray = [1,3,5,7,9];

function reverseArrayInPlace (someArray) {
	var MiddleIndex = (Math.floor(someArray.length/2));
	for (var i = 0;  i <= MiddleIndex-1; i++) {
		var currentValue = someArray[i];
		var mirrorIndex = someArray[someArray.length -i -1];
		var temp = currentValue;
		currentValue = mirrorIndex;
		mirrorIndex = temp;
	}
		
	return someArray;
}

console.log(reverseArrayInPlace(sampleArray));

3
  • 3
    You aren't assigning the values back into the array. After var temp = currentValue you need someArray[i] = mirrorIndex;, etc. You also don't need currentValue, you can just do var temp = someArray[i];. And mirrorIndex is poorly named, consider mirrorValue. Commented Dec 25, 2014 at 12:07
  • where you set reversed array back to someArray variable, it was still having old array Commented Dec 25, 2014 at 12:08
  • Did any of these answers work for you? Commented Dec 29, 2014 at 5:40

7 Answers 7

2

As others already noticed, you forgot an assignment, because currentValue = mirrorIndex; just changes the value of currentValue, not the element within the array itself. Same goes for temp. More general: you can't store an Array element into a variable as a reference to that Arrayelement like that.

It also makes your function look overly complex. Here are two alternatives. In the first the swap is done by storing one value, replace the element, and assigning the stored value to the other element. In the sceond the same is done in one line, using Array.splice (see MDN).

Here is a test for the performance of 3 in place reverse functions.

function reverseInPlace(arr) {
 var len = arr.length-1, mid = Math.floor(len/2), i = -1;
 while( i++ < mid ) {
   var swap = arr[len-i]; // save swapvalue
   arr[len-i] = arr[i];   // assign current value to swap position
   arr[i] = swap;         // assign swapvalue to current position
 }
}

// Swapping in one line (using splice)
function reverseInPlace2(arr) {
 var mid = Math.floor(arr.length/2), i = -1;
 while( i++ < mid ) { arr[i] = arr.splice(-(i+1), 1, arr[i])[0]; }
}

// demo
var log = Helpers.log2Screen;
var arr = [1,2,3,4];
reverseInPlace(arr);
log( 'Even length: `reverseInPlace(arr) -&gt; [', arr, ']`' );

arr = [1,2,3,4,5,6,7];
reverseInPlace(arr);
log( 'Odd length: `reverseInPlace(arr) -&gt; [', arr, ']`' );

arr = [1,2,3,4,5];
reverseInPlace2(arr);
log( 'Use `Array.splice: reverseInPlace2(arr4) -&gt; [', arr, ']`' );

// clarification of what happens in your code
log('\n<b>Clarification of what happens in your code</b>');

var myArr = [1,2,3,4,5];
var el2 = myArr[2];

log('Assigned: `MyArr: ', myArr, ', el2: ', el2, '`'); 
log( 'Storing: `var el2 = myArr[2];`' );
el2 = myArr[0];
log( 'Assigning: `el2 = myArr[0];`' );
log( '`myArray` did not change `MyArr: ', myArr, '`' ); 
log( 'But `el2` did: ', '`el2: ', el2, '`' );
<!-- some helpers -->
<script src="https://rawgit.com/KooiInc/Helpers/master/Helpers-min.js"></script>

Sign up to request clarification or add additional context in comments.

6 Comments

"Reverse in place" sorta kinda implies that copies of things are not being kept around, or in other words that the storage complexity is O(1). In that sense, your first example does not really fulfill the spirit of the problem. +1 for showing us Helpers.log2Screen.
@torazaburo: thanks. That's why I included reverseInPlace2 ;)
When I run reverseInPlace2 with an input of [1,2,3,4], it seems to give me [4,2,3,1], so I think you've got an off-by-one error lurking somewhere in your code.
Yep, corrected it, and added some code for demonstration.
"Can anyone show me where I'm going wrong with this function on reversing arrays?" ... your opinion on the complexity of the function isn't really answering that.
|
1

Instead of reversing the array, we'll create a shadow array of getters which retrieve the elements in reversed order:

function reverse_shadow(arr) {
    var o = [];
    o.length = arr.length;
    arr.forEach(function(elt, i) {
        Object.defineProperty(o, i, { 
            get: function() { return arr[arr.length - i - 1]; } 
        });
    });
    return o;
}

var arr = [1, 2, 3, 4];
var reversed = reverse_shadow(arr);

>> reversed.join(' ')
<< "4 3 2 1"

By adding the code below into the middle of the function, we can extend this to automatically update the shadow when elements are added to the underlying array, without having to call reverse_shadow again:

Object.observe(arr, function(changes) {
    changes.forEach(function(change) {
        if (change.name === 'length') { o.length = arr.length; }
        else if (change.type === 'add') {
            Object.defineProperty(o, change.name, {
                get: function() { return arr[arr.length - change.name - 1]; }
            });
        }
    });
});

>> arr.push(5);
>> reversed.join(' ')
<< "5 4 3 2 1"

1 Comment

This must be the accepted answer. It accomplishes reversal without reversing anything!
1

Hey so here is my solution, I think it works pretty well:

function reverseInPlace(array) {
    for (var i = 0; i<array.length; i+=2) {
        array.unshift(array[i]);
    }
    array.splice(Math.floor(array.length/2), array.length/2);
    return array;
}

Comments

0

This version would seem to be doing the bare minimum.

// Swap the first element with the last,
// then the 2nd with the 2nd-to-last, etc.
// Quit when the indices meet or pass in the middle.

var reverseArrayInPlace = function(array) {
  for(var left =0, rite = array.length-1; left < rite; left++, rite--){
    var leftcopy = array[left];
    array[left] = array[rite];
    array[rite] = leftcopy;
  }
}

var arrayValue = [1, 2, 3, 4, 5];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
// → [5, 4, 3, 2, 1]

Comments

0

This could be one possible solution but I am not sure if it does the reverse in place. Since I create a map to store the values, then place them in reverse order in the original array.

function reverseArrayInPlace(array){
    var map = {};
  for(var i = 0; i < array.length; i++){
    map[i] = array[i];
  }

  for(var i = 0; i <= (array.length - 1); i++){
    array[i] = map[(array.length - 1) - i];
  }

  return array;
}

Comments

0

Here is my solution for this :

function reverseArrayInPlace(arr){
  for(let i of [...arr]) {
    arr.unshift(i) 
    arr.pop()
 }
}

let arrayValue = [1, 2, 3, 4, 5];

reverseArrayInPlace(arrayValue);

console.log(arrayValue);

Comments

0

Here my solution for task in eloquent JS (3rd edition)

let numArray = [1, 2, 3, 4, 5];
reverseArrayInPlace(numArray);

function reverseArrayInPlace(number) {
    let newArray = [];
    for (let numbers of number) {
        newArray.unshift(numbers);
    }
    console.log(newArray);
}

// -> [ 5, 4, 3, 2, 1 ]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.