Matriz inversa en Javascript sin mutar la matriz original

Respuestas:

377

Puede utilizar slice () para hacer una copia a continuación inversa () se

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

Arun P Johny
fuente
¿Puedes por favor explicar slice () sin parámetros?
Alex
3
@Alex slice - If begin is omitted, slice begins from index 0.- entonces es lo mismo quearray.slice(0)
Arun P Johny
2
Creo que @Alex quería decir 'explícalo en tu respuesta' ... independientemente ... Solución brillante. ¡Gracias!
sfletche
14
NO recomendaría usar este enfoque, porque es una práctica muy engañosa. Es muy confuso cuando usas slice () y en realidad no estás cortando nada. Si necesita un reverso inmutable, simplemente cree una nueva copia nueva: const newArray = [... array] .reverse ()
Oleg Matei
105

En ES6:

const newArray = [...array].reverse()
Brian M. Hunt
fuente
2
¿Cómo se compara el rendimiento de esto con el de la respuesta aceptada? ¿Son lo mismo?
Katie
@Katie Muy similar, ambos muy rápidos, con Chrome pareciendo dar [...].reverseuna ventaja en un caso de prueba muy simple. jsperf.com/reverse-vs-slice-reverse/1
Brian M. Hunt
44
Constantemente me estoy volviendo .slicesignificativamente más rápido.
James Coyle el
3
@JamesCoyle Es probable que dependa del navegador y del sistema operativo, pero slicees probable que sea más rápido porque b / c [...]es un genérico iterable a matriz, por lo que no puede hacer tantas suposiciones. Además, es probable que sliceesté mejor optimizado b / c que haya existido durante mucho tiempo.
Brian M. Hunt el
Mis pensamientos exactamente.
James Coyle el
11

Otra variante ES6:

También podemos usar .reduceRight()para crear una matriz invertida sin realmente invertirla.

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

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

console.log(B);

Recursos utiles:

Mohammad Usman
fuente
2
reduceRightes lento af
Dragos Rizescu
@DragosRizescu ¿Puedes compartir algunos resultados de prueba de muestra?
Mohammad Usman
1
Aquí hay un repositorio con el que puedes jugar: (no es el mejor ejemplo, pero tuve esta discusión con alguien hace un tiempo en un contexto de Reacción, por lo que lo he reunido): github.com/rizedr/reduce-vs-reduceRight
Dragos Rizescu
44
(a, c) => a.concat([c])se siente más idiomático que(a, c) => (a.push(c), a)
Kyle Lin
1
@DragosRizescu en realidad parece que esta es la más rápida de las 3 respuestas principales. jsperf.com/reverse-vs-slice-reverse/3
DBosley
7

Prueba esta solución recursiva:

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
fuente
1
Parece que se rompería para matrices vacías.
Matthias
6

Una alternativa ES6 usando .reduce()y difundiendo.

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

Básicamente, lo que hace es crear una nueva matriz con el siguiente elemento en foo y distribuir la matriz acumulada para cada iteración después de b.

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

Alternativamente, .reduceRight()como se mencionó anteriormente aquí, pero sin la .push()mutación.

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

Hay varias formas de invertir una matriz sin modificarla. Dos de ellos son

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

Prueba de rendimiento http://jsben.ch/guftu

shekhardtu
fuente
0

EN Javascript simple:

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

  return newArray;
}
Amit kumar
fuente
0

Invertir en su lugar con intercambio variable solo con fines demostrativos (pero necesita una copia si no desea mutar)

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
fuente
-4

es6:

const reverseArr = [1,2,3,4].sort(()=>1)
Radion Ponomarenko
fuente
44
Bienvenido a SO, Radion! Al dejar una respuesta, generalmente es una buena idea explicar por qué su respuesta funciona y por qué llegó a esta conclusión, esto ayuda a los usuarios más nuevos a comprender las interacciones y los idiomas que ha especificado.
Ethan Field
En defensa de Radion: P que 1al final podría haber sido algo mayor que cero, porque así es como funciona la Array.prototype.sortdevolución de llamada (o así llamada compare function). Básicamente, siempre se comparan 2 números y en este caso la comparación siempre es positiva, por lo que siempre se pasa al segundo número delante del primero :) esto es muy explicativo: stackoverflow.com/questions/6567941/…
iulial
8
sort()muta la matriz (es decir, la ordena en su lugar), que es lo que el OP quiere evitar.
Clint Harris
55
Esta respuesta es incorrecta de varias maneras. (1) muta la matriz, como señala @ClintHarris, por lo que no es mejor que .reverse (). (2) su comparador es ilegal: cuando devuelve 1 para a, b, debe devolver un número negativo para b, a. Si su respuesta invierte la matriz en algunas implementaciones, es completamente por suerte.
Don Hatch