Reverse array in Javascript without mutating original array

JavascriptArrays

Javascript Problem Overview


Array.prototype.reverse reverses the contents of an array in place (with mutation)...

Is there a similarly simple strategy for reversing an array without altering the contents of the original array (without mutation)?

Javascript Solutions


Solution 1 - Javascript

You can use slice() to make a copy then reverse() it

var newarray = array.slice().reverse();

var array = ['a', 'b', 'c', 'd', 'e'];
var newarray = array.slice().reverse();

console.log('a', array);
console.log('na', newarray);

Solution 2 - Javascript

In ES6:

const newArray = [...array].reverse()

Solution 3 - Javascript

Another ES6 variant:

We can also use .reduceRight() to create a reversed array without actually reversing it.

let A = ['a', 'b', 'c', 'd', 'e', 'f'];

let B = A.reduceRight((a, c) => (a.push(c), a), []);

console.log(B);

Useful Resources:

Solution 4 - Javascript

Try this recursive solution:

const reverse = ([head, ...tail]) => 
    tail.length === 0
        ? [head]                       // Base case -- cannot reverse a single element.
        : [...reverse(tail), head]     // Recursive case

reverse([1]);               // [1]
reverse([1,2,3]);           // [3,2,1]
reverse('hello').join('');  // 'olleh' -- Strings too!                              

Solution 5 - Javascript

There are multiple ways of reversing an array without modifying. Two of them are

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

// Using Splice
var reverseArray1 = array.splice().reverse(); // Fastest

// Using spread operator
var reverseArray2 = [...array].reverse();

// Using for loop 
var reverseArray3 = []; 
for(var i = array.length-1; i>=0; i--) {
  reverseArray.push(array[i]);
}

Performance test http://jsben.ch/guftu

Solution 6 - Javascript

An ES6 alternative using .reduce() and spreading.

const foo = [1, 2, 3, 4];
const bar = foo.reduce((acc, b) => ([b, ...acc]), []);

Basically what it does is create a new array with the next element in foo, and spreading the accumulated array for each iteration after b.

[]
[1] => [1]
[2, ...[1]] => [2, 1]
[3, ...[2, 1]] => [3, 2, 1]
[4, ...[3, 2, 1]] => [4, 3, 2, 1]

Alternatively .reduceRight() as mentioned above here, but without the .push() mutation.

const baz = foo.reduceRight((acc, b) => ([...acc, b]), []);

Solution 7 - Javascript

const newArr = Array.from(originalArray).reverse();

Solution 8 - Javascript

const arrayCopy = Object.assign([], array).reverse()

This solution:

-Successfully copies the array

-Doesn't mutate the original array

-Looks like it's doing what it is doing

Solution 9 - Javascript

Reversing in place with variable swap just for demonstrative purposes (but you need a copy if you don't want to mutate)

const myArr = ["a", "b", "c", "d"];
const copy = [...myArr];
for (let i = 0; i < (copy.length - 1) / 2; i++) {  
    const lastIndex = copy.length - 1 - i; 
    [copy[i], copy[lastIndex]] = [copy[lastIndex], copy[i]] 
}

Solution 10 - Javascript

While array.slice().reverse() is what I would myself go for in a situation where I cannot use a library, it's not so good in terms of readability: we are using imperative logic that the person reading the code must think through. Considering also that there is the same problem with sort, there's a solid justification here for using a utility library.

You can use a function pipe from fp-ts or a library I've written myself. It pipes a value though a number of functions, so pipe(x, a, b) is equivalent to b(a(x)). With this function, you can write

pipe(yourArray, reverseArray)

where reverseArray is a function that basically does .slice().reverse(), i.e. reverses the array immutably. Generally speaking, pipe lets you do the equivalent of dot-chaining, but without being limited to the methods available on the array prototype.

Solution 11 - Javascript

There's a new tc39 proposal, which adds a toReversed method to Array that returns a copy of the array and doesn't modify the original.

Example from the proposal:

const sequence = [1, 2, 3];
sequence.toReversed(); // => [3, 2, 1]
sequence; // => [1, 2, 3]

As it's currently in stage 3, it will likely be implemented in browser engines soon, but in the meantime a polyfill is available here or in core-js.

Solution 12 - Javascript

INTO plain Javascript:

function reverseArray(arr, num) {
  var newArray = [];
  for (let i = num; i <= arr.length - 1; i++) {
    newArray.push(arr[i]);
  }
   
  return newArray;
}

Solution 13 - Javascript

es6:

const reverseArr = [1,2,3,4].sort(()=>1)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsfletcheView Question on Stackoverflow
Solution 1 - JavascriptArun P JohnyView Answer on Stackoverflow
Solution 2 - JavascriptBrian M. HuntView Answer on Stackoverflow
Solution 3 - JavascriptMohammad UsmanView Answer on Stackoverflow
Solution 4 - JavascriptAustin KeetonView Answer on Stackoverflow
Solution 5 - JavascriptshekhardtuView Answer on Stackoverflow
Solution 6 - JavascripthanswilwView Answer on Stackoverflow
Solution 7 - JavascriptRaghuView Answer on Stackoverflow
Solution 8 - Javascripta_few_diDDLeRsView Answer on Stackoverflow
Solution 9 - Javascriptdaino3View Answer on Stackoverflow
Solution 10 - JavascriptIvanView Answer on Stackoverflow
Solution 11 - JavascriptJoshView Answer on Stackoverflow
Solution 12 - JavascriptAmit kumarView Answer on Stackoverflow
Solution 13 - JavascriptRadion PonomarenkoView Answer on Stackoverflow