Array.prototype.reverse
inverte o conteúdo de uma matriz no local (com mutação) ...
Existe uma estratégia igualmente simples para reverter uma matriz sem alterar o conteúdo da matriz original (sem mutação)?
Array.prototype.reverse
inverte o conteúdo de uma matriz no local (com mutação) ...
Existe uma estratégia igualmente simples para reverter uma matriz sem alterar o conteúdo da matriz original (sem mutação)?
Respostas:
Você pode usar o slice () para fazer uma cópia, em seguida, reverse () que
var newarray = array.slice().reverse();
If begin is omitted, slice begins from index 0.
- por isso, é o mesmo quearray.slice(0)
No ES6:
const newArray = [...array].reverse()
[...].reverse
uma vantagem em um caso de teste muito simples. jsperf.com/reverse-vs-slice-reverse/1
.slice
significativamente mais rápido.
slice
é provável que seja mais rápido , pois o b / c [...]
é um iterável para matriz genérico, portanto não pode fazer tantas suposições. Além disso, é provável que slice
seja melhor otimizado porque já existe há muito tempo.
Outra variante do ES6:
Também podemos usar .reduceRight()
para criar uma matriz invertida sem realmente revertê-la.
let A = ['a', 'b', 'c', 'd', 'e', 'f'];
let B = A.reduceRight((a, c) => (a.push(c), a), []);
console.log(B);
Recursos úteis:
reduceRight
é lento af
(a, c) => a.concat([c])
se sente mais idiomática que(a, c) => (a.push(c), a)
Experimente esta solução 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!
Uma alternativa ES6 usando .reduce()
e espalhando.
const foo = [1, 2, 3, 4];
const bar = foo.reduce((acc, b) => ([b, ...acc]), []);
Basicamente, o que ele faz é criar uma nova matriz com o próximo elemento em foo e espalhar a matriz acumulada para cada iteração após b.
[]
[1] => [1]
[2, ...[1]] => [2, 1]
[3, ...[2, 1]] => [3, 2, 1]
[4, ...[3, 2, 1]] => [4, 3, 2, 1]
Alternativamente, .reduceRight()
como mencionado acima aqui, mas sem a .push()
mutação.
const baz = foo.reduceRight((acc, b) => ([...acc, b]), []);
Existem várias maneiras de reverter uma matriz sem modificar. Dois deles são
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]);
}
Teste de desempenho http://jsben.ch/guftu
INTO Javascript simples:
function reverseArray(arr, num) {
var newArray = [];
for (let i = num; i <= arr.length - 1; i++) {
newArray.push(arr[i]);
}
return newArray;
}
Reversão no local com troca de variável apenas para fins demonstrativos (mas você precisa de uma cópia se não quiser fazer a mutação)
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]]
}
es6:
const reverseArr = [1,2,3,4].sort(()=>1)
1
no final poderia ter sido maior que zero, porque é assim que o Array.prototype.sort
retorno de chamada (ou o chamado compare function
) funciona. Basicamente, você sempre compara 2 números e, nesse caso, a comparação retorna sempre positiva, por isso diz sempre mover para o segundo número na frente do primeiro :) isso é muito explicativo: stackoverflow.com/questions/6567941/…
sort()
modifica a matriz (ou seja, classifica-a no lugar), que é o que o OP deseja evitar.