Inverser le tableau en Javascript sans muter le tableau d'origine

Réponses:

416

Vous pouvez utiliser slice () pour faire une copie puis inverse () il

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

Arun P Johny
la source
Pouvez-vous s'il vous plaît expliquer slice () sans paramètres?
Alex
4
@Alex slice - If begin is omitted, slice begins from index 0.- c'est donc la même chose quearray.slice(0)
Arun P Johny
2
Je pense que @Alex voulait dire 'expliquez-le dans votre réponse' ... peu importe ... Solution brillante. Merci!
sfletche
18
Je ne recommanderais PAS d'utiliser cette approche, car c'est une pratique très trompeuse. C'est très déroutant lorsque vous utilisez slice () et que vous ne découpez rien. Si vous avez besoin d'un reverse immuable, créez simplement une nouvelle copie: const newArray = [... array] .reverse ()
Oleg Matei
1
Pouvons-nous tous prendre un moment pour identifier la quantité supplémentaire de JavaScript nécessaire pour se développer? C'est le meilleur que nous ayons? Cmon JavaScript! grandis un peu.
Gant Laborde
121

Dans ES6:

const newArray = [...array].reverse()
Brian M. Hunt
la source
2
Comment la performance de ceci se compare-t-elle à celle de la réponse acceptée? Sont-ils les mêmes?
Katie
5
Je deviens toujours .sliceaussi beaucoup plus rapide.
James Coyle
3
@JamesCoyle Cela dépend probablement du navigateur et du système d'exploitation, mais il slicesera probablement plus rapide b / c [...]est un tableau générique itérable donc ne peut pas faire autant de suppositions. De plus, il est probable que ce slicesoit mieux optimisé car cela existe depuis longtemps.
Brian M. Hunt
Mes pensées exactement.
James Coyle
11

Une autre variante ES6:

Nous pouvons également utiliser .reduceRight()pour créer un tableau inversé sans réellement l'inverser.

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

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

console.log(B);

Ressources utiles:

Mohammad Usman
la source
2
reduceRightis slow af
Dragos Rizescu
@DragosRizescu Pouvez-vous partager quelques exemples de résultats de test?
Mohammad Usman
1
Voici un repo avec lequel vous pouvez jouer: (pas le meilleur exemple, mais j'ai eu cet argument avec quelqu'un il y a quelque temps dans un contexte React, donc je l'ai mis ensemble): github.com/rizedr/reduce-vs-reduceRight
Dragos Rizescu
4
(a, c) => a.concat([c])se sent plus idiomatique que(a, c) => (a.push(c), a)
Kyle Lin
1
@DragosRizescu, il semble en fait que c'est la plus rapide des 3 meilleures réponses. jsperf.com/reverse-vs-slice-reverse/3
DBosley
7

Essayez cette solution récursive:

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!                              
Austin Keeton
la source
1
Cela semble casser pour les tableaux vides.
Matthias
6

Une alternative ES6 utilisant .reduce()et épandant .

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

Fondamentalement, il crée un nouveau tableau avec l'élément suivant dans foo, et répartit le tableau accumulé pour chaque itération après b.

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

Alternativement .reduceRight()comme mentionné ci-dessus ici, mais sans la .push()mutation.

const baz = foo.reduceRight((acc, b) => ([...acc, b]), []);
hanswilw
la source
4

Il existe plusieurs façons d'inverser un tableau sans le modifier. Deux d'entre eux sont

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]);
}

Test de performance http://jsben.ch/guftu

Shekhardtu
la source
0

EN Javascript brut:

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

  return newArray;
}
Amit Kumar
la source
0

Inverser en place avec échange de variables juste à des fins de démonstration (mais vous avez besoin d'une copie si vous ne voulez pas muter)

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]] 
}

daino3
la source
-4

es6:

const reverseArr = [1,2,3,4].sort(()=>1)
Radion Ponomarenko
la source
5
Bienvenue à SO, Radion! Lorsque vous laissez une réponse, il est généralement judicieux d'expliquer pourquoi votre réponse fonctionne et pourquoi vous êtes arrivé à cette conclusion, cela aide les nouveaux utilisateurs à comprendre les interactions et les langues que vous avez spécifiées.
Ethan Field le
Dans la défense de Radion: P qui 1à la fin aurait pu être supérieur à zéro, car c'est ainsi que fonctionne le Array.prototype.sortrappel (ou ainsi appelé compare function). En gros, vous comparez toujours 2 nombres et dans ce cas, la comparaison retourne toujours positive, donc il est dit de toujours passer au deuxième nombre devant le premier :) c'est très explicatif: stackoverflow.com/questions/6567941
...
8
sort()mute le tableau (c'est-à-dire le trie sur place), ce que l'OP veut éviter.
Clint Harris
5
Cette réponse est erronée à plusieurs égards. (1) il mute le tableau, comme le souligne @ClintHarris, donc ce n'est pas mieux que .reverse (). (2) votre comparateur est illégal - lorsque vous renvoyez 1 pour a, b, vous devez renvoyer un nombre négatif pour b, a. Si votre réponse inverse le tableau sur certaines implémentations, c'est entièrement par chance.
Don Hatch