6

I want to reverse an array without using reverse() function like this:

function reverse(array){
    var output = [];
    for (var i = 0; i<= array.length; i++){
        output.push(array.pop());
    }

    return output;
}

console.log(reverse([1,2,3,4,5,6,7]));

However, the it shows [7, 6, 5, 4] Can someone tell me, why my reverse function is wrong? Thanks in advance!

Zichen Ma
  • 77
  • 1
  • 1
  • 5
  • what do you want it to show you? – happymacarts Nov 22 '16 at 20:42
  • 1
    How are there this many answers to this question? None of which mention reversing in place. http://stackoverflow.com/questions/5276953/what-is-the-most-efficient-way-to-reverse-an-array-in-javascript has – AJ X. Nov 22 '16 at 20:47
  • 2
    @axlj, "how are there this many answers..." because there's more than one way to skin a cat, and in this case reverse the cat as well. – zzzzBov Nov 22 '16 at 20:59
  • @zzzzBov I should have clarified -- ... Identical answers :-) – AJ X. Nov 22 '16 at 21:18

24 Answers24

13

array.pop() removes the popped element from the array, reducing its size by one. Once you're at i === 4, your break condition no longer evaluates to true and the loop ends.


One possible solution:

function reverse(array) {
  var output = [];
  while (array.length) {
    output.push(array.pop());
  }

  return output;
}

console.log(reverse([1, 2, 3, 4, 5, 6, 7]));
TimoStaudinger
  • 38,697
  • 15
  • 86
  • 91
5

You can make use of Array.prototype.reduceright and reverse it

check the following snippet

var arr = ([1, 2, 3, 4, 5, 6, 7]).reduceRight(function(previous, current) {
  previous.push(current);
  return previous;
}, []);

console.log(arr);
zzzzBov
  • 167,057
  • 51
  • 314
  • 358
Geeky
  • 7,214
  • 2
  • 23
  • 49
4

No need to pop anything... Just iterate through the existing array in reverse order to make your new one.

function reverse(array){
    var output = [];
    for (var i = array.length - 1; i> -1; i--){
        output.push(array[i]);
    }

    return output;
}

console.log(reverse([1,2,3,4,5,6,7]));

Edit after answer got accepted.

A link in a comment on your opening post made me test my way VS the accepted answer's way. I was pleased to see that my way, at least in my case, turned out to be faster every single time. By a small margin but, faster non the less.

Here's the copy/paste of what I used to test it (tested from Firefox developer scratch pad):

function reverseMyWay(array){
    var output = [];
    for (var i = array.length - 1; i> -1; i--){
        output.push(array[i]);
    }

    return output;
}

function reverseTheirWay(array) {
  var output = [];
  while (array.length) {
    output.push(array.pop());
  }

  return output;
}

function JustDoIt(){
    console.log("their way starts")
    var startOf = new Date().getTime();
    for(var p = 0; p < 10000; p++)
        {
            console.log(reverseTheirWay([7,6,5,4,3,2,1]))
        }
    var endOf = new Date().getTime();
    console.log("ran for " + (endOf - startOf) + " ms");
    console.log("their way ends")

}


function JustDoIMyWay(){
    console.log("my way starts")
    var startOf = new Date().getTime();
    for(var p = 0; p < 10000; p++)
        {
            console.log(reverseMyWay([7,6,5,4,3,2,1]))
        }
    var endOf = new Date().getTime();
    console.log("ran for " + (endOf - startOf) + " ms");
    console.log("my way ends")
}

JustDoIt();
JustDoIMyWay();
blaze_125
  • 2,165
  • 1
  • 8
  • 18
4

In ES6 this could be written as

reverse = (array) => array.map(array.pop, [... array]);
Mike Szyndel
  • 10,124
  • 7
  • 44
  • 61
  • 1
    Welcome to StackOverflow. While this code may solve the question, [including an explanation](https://meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit](https://stackoverflow.com/posts/65328348/edit) your answer to add explanations and give an indication of what limitations and assumptions apply. – Ruli Dec 16 '20 at 18:46
4

Solution to reverse an array without using built-in function and extra space.

let arr = [1, 2, 3, 4, 5, 6, 7];
let n = arr.length-1;

for(let i=0; i<=n/2; i++) {
  let temp = arr[i];
  arr[i] = arr[n-i];
  arr[n-i] = temp;
}
console.log(arr);
akhtarvahid
  • 8,226
  • 2
  • 18
  • 27
2

Do it in a reverse way, Because when you do .pop() every time the array's length got affected.

function reverse(array){
    var output = [];
    for (var i = array.length; i > 0; i--){
        output.push(array.pop());
    }
    return output;
}

console.log(reverse([1,2,3,4,5,6,7]));

Or you could cache the length of the array in a variable before popping out from the array,

function reverse(array){
    var output = [];
    for (var i = 0, len= array.length; i< len; i++){
        output.push(array.pop());
    }

    return output;
}

console.log(reverse([1,2,3,4,5,6,7]));
Rajaprabhu Aravindasamy
  • 64,912
  • 15
  • 96
  • 124
2

You are modifying the existing array with your reverse function, which is affecting array.length.

Don't pop off the array, just access the item in the array and unshift the item on the new array so that the first element of the existing array becomes the last element of the new array:

function reverse(array){
  var output = [],
      i;
  for (i = 0; i < array.length; i++){
    output.unshift(array[i]);
  }

  return output;
}

console.log(reverse([1,2,3,4,5,6,7]));

If you'd like to modify the array in-place similar to how Array.prototype.reverse does (it's generally inadvisable to cause side-effects), you can splice the array, and unshift the item back on at the beginning:

function reverse(array) {
  var i,
      tmp;
  for (i = 1; i < array.length; i++) {
    tmp = array.splice(i, 1)[0];
    array.unshift(tmp);
  }
  return array;
}

var a = [1, 2, 3, 4, 5];
console.log('reverse result', reverse(a));
console.log('a', a);
zzzzBov
  • 167,057
  • 51
  • 314
  • 358
2

This piece allows to reverse the array in place, without pop, splice, or push.

var arr = [1, 2, 3, 4, 5];
function reverseArrayInPlace(arr2) {
  var half = Math.floor(arr2.length / 2);
  for (var i = 0; i < half; i++) {
    var temp = arr2[arr2.length - 1 - i];
    arr2[arr2.length - 1 - i] = arr2[i];
    arr2[i] = temp;
  }
  return arr2;
}
shimmiChristo
  • 33
  • 1
  • 6
1

As you pop items off the first array, it's length changes and your loop count is shortened. You need to cache the original length of the original array so that the loop will run the correct amount of times.

function reverse(array){
    var output = [];
    var len = array.length;
    for (var i = 0; i< len; i++){
        output.push(array.pop());
    }

    return output;
}

console.log(reverse([1,2,3,4,5,6,7]));
Scott Marcus
  • 60,351
  • 6
  • 44
  • 64
1

You're modifying the original array and changing it's size. instead of a for loop you could use a while

    function reverse(array){
        var output = [];
        while(array.length){
            //this removes the last element making the length smaller
            output.push(array.pop());
        }

        return output;
}

console.log(reverse([1,2,3,4,5,6,7]));
nottu
  • 360
  • 1
  • 12
1

function rvrc(arr) {
  for (let i = 0; i < arr.length / 2; i++) {
    const buffer = arr[i];

    arr[i] = arr[arr.length - 1 - i];
    arr[arr.length - 1 - i] = buffer;
  }
};
akula
  • 11
  • 4
0

This happens because every time you do array.pop(), whilst it does return the last index in the array, it also removes it from the array. The loop recalculates the length of the array at each iteration. Because the array gets 1 index shorter at each iteration, you get a much shorter array returned from the function.

Liran H
  • 7,079
  • 6
  • 32
  • 43
0

Here, let's define the function

function rev(arr) {
  const na = [];
  for (let i=0; i<arr.length; i++) {
    na.push(arr[arr.length-i])
  }
  return na;
}

Let's say your array is defined as 'abca' and contains ['a','b','c','d','e','foo','bar']

We would do:

var reva = rev(abca)

This would make 'reva' return ['bar','foo','e','d','c','b','a']. I hope I helped!

0

This piece of code will work without using a second array. It is using the built in method splice.

function reverse(array){
    for (let i = 0; i < array.length; i++) {
        array.splice(i, 0, array.splice(array.length - 1)[0]);
    }
    return array;
}
viz_tm
  • 105
  • 1
  • 1
  • 6
0

You can use .map as it is perfect for this situation and is only 1 line:

const reverse = a =>{ i=a.length; return a.map(_=>a[i-=1]) }

This will take the array, and for each index, change it to the length of the array - index, or the opposite side of the array.

0

with reverse for loop


let array = ["ahmet", "mehmet", "aslı"]


    length = array.length
    newArray = [];
    for (let i = length-1; i >-1; i--) {

        newArray.push(array[i])

    }

    console.log(newArray)
dılo sürücü
  • 2,921
  • 1
  • 15
  • 24
0

And this one:

function reverseArray(arr) { 
    let top = arr.length - 1;
    let bottom = 0;
    let swap = 0;
    
    while (top - bottom >= 1) {
        swap = arr[bottom];
        arr[bottom] = arr[top];
        arr[top] = swap;
        bottom++;
        top--;
    }
}
oikumo
  • 1
0
function reverse(arr) {
  for (let i = 0; i < arr.length - 1; i++) {
    arr.splice(i, 0, arr.pop())
  }
  return arr;
}
console.log(reverse([1, 2, 3, 4, 5]))
//without another array
  • 3
    While this code block may answer the question, it would be best if you could provide a little explanation for why it does so. – nik7 Apr 26 '21 at 22:23
  • 1
    ...especially on a question that's almost 4.5 years old with 19 existing answers. How does this improve upon what's already here? – Chris Apr 27 '21 at 00:40
0
reverse=a=>a.map((x,y)=>a[a.length-1-y])

reverse=a=>a.map((x,y)=>a[a.length-1-y])

console.log(reverse(["Works","It","One","Line"]))
Bugs Bunny
  • 35
  • 5
0

One of shortest:

let reverse = arr = arr.map(arr.pop, [...arr])

Oleksandr Tkalenko
  • 1,081
  • 12
  • 21
0

This is an old question, but someone may find this helpful.

There are two main ways to do it:

First, out of place, you basically push the last element to a new array, and use the new array:

function arrReverse(arr) {
    let newArr = [];
            for(let i = 0; i<arr.length; i++){    
            newArr.push(arr.length -1 -i);       
    }
    return newArr;
}

arrReverse([0,1,2,3,4,5,6,7,8,9]);

Then there's in place. This is a bit tricky, but the way I think of it is like having four objects in front of you. You need to hold the first in your hand, then move the last item to the first place, and then place the item in your hand in the last place. Afterwards, you increase the leftmost side by one and decrease the rightmost side by one:

function reverseArr(arr) {
    let lh;
        
    for(let i = 0; i<arr.length/2; i++){
    
            lh = arr[i];
        arr[i] = arr[arr.length -i -1];
        arr[arr.length -i -1] = lh;
        
    }
    return arr;
}

reverseArr([0,1,2,3,4,5,6,7,8,9]);

Like so. I even named my variable lh for "left hand" to help the idea along.

Understanding arrays is massively important, and figuring out how they work will not only save you from unnecessarily long and tedious ways of solving this, but will also help you grasp certain data concepts way better!

0

I found a way of reversing the array this way:

function reverse(arr){
  for (let i = arr.length-1; i >= 0; i--){ 
    arr.splice(i, 0, arr.shift());
    }
  return arr;
}
Irkenn
  • 1
  • 2
-1
function reverse(str1) {
  let newstr = [];
  let count = 0;
  for (let i = str1.length - 1; i >= 0; i--) {
    newstr[count] = str1[i];
    count++;
  }
  return newstr;
}
reverse(['x','y','z']);
-1

Array=[2,3,4,5]

 for(var i=0;i<Array.length/2;i++){
    var temp =Array[i];
    Array[i]=Array[Array.length-i-1]
    Array[Array.length-i-1]=temp
}

console.log(Array) //[5,4,3,2]