Odwróć tablicę w JavaScript bez mutowania oryginalnej tablicy


Odpowiedzi:


375

Można użyć slice () , aby wykonać kopię następnie reverse () go

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


Czy możesz wyjaśnić funkcję slice () bez parametrów?
— Alex

3
@Alex slice - If begin is omitted, slice begins from index 0.- więc jest taki sam jakarray.slice(0)
— Arun P. Johny

2
Myślę, że @Alex oznaczało „wyjaśnij to w swojej odpowiedzi” ... niezależnie od tego ... Świetne rozwiązanie. Dzięki!
— sfletche

12
NIE zalecałbym stosowania tego podejścia, ponieważ jest to bardzo myląca praktyka. Jest to bardzo mylące, gdy używasz slice () i tak naprawdę niczego nie kroisz. Jeśli potrzebujesz niezmiennego odwrotu, po prostu utwórz świeżą nową kopię: const newArray = [... array] .reverse ()
— Oleg Matei

104

W ES6:

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

2
Jak wypada to w porównaniu z przyjętą odpowiedzią? Czy oni są tacy sami?
— Katie,

@Katie Bardzo podobne, oba bardzo szybkie, a Chrome wydaje się dawać [...].reverseprzewagę w bardzo prostym przypadku testowym. jsperf.com/reverse-vs-slice-reverse/1
— Brian M. Hunt

4
Konsekwentnie robię się .sliceznacznie szybszy.
— James Coyle

3
@JamesCoyle Prawdopodobnie zależy od przeglądarki i systemu operacyjnego, ale sliceprawdopodobnie będzie szybszy b / c [...]jest ogólną iterowalną tablicą, więc nie można przyjąć tylu założeń. Jest również prawdopodobne, że slicejest lepiej zoptymalizowany b / c, to już dawno temu.
— Brian M. Hunt

Dokładnie moje myśli.
— James Coyle

11

Kolejny wariant ES6:

Możemy również użyć .reduceRight()do utworzenia odwróconej tablicy bez jej odwracania.

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

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

console.log(B);

Przydatne zasoby:


2
reduceRightjest wolny af
— Dragos Rizescu

@DragosRizescu Czy możesz podzielić się przykładowymi wynikami testów?
— Mohammad Usman

1
Oto repozytorium, z którym możesz grać: (nie jest to najlepszy przykład, ale miałem ten argument z kimś jakiś czas temu w kontekście React, dlatego złożyłem
— Dragos Rizescu

4
(a, c) => a.concat([c])czuje się bardziej idiomatyczny niż(a, c) => (a.push(c), a)
— Kyle Lin,

1
@DragosRizescu faktycznie wygląda na to, że jest to najszybsza z 3 najlepszych odpowiedzi. jsperf.com/reverse-vs-slice-reverse/3
— DBosley

7

Wypróbuj to rozwiązanie rekurencyjne:

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!                              

1
Wygląda na to, że zepsuje się dla pustych tablic.
— Matthias,

6

Alternatywa ES6 przy użyciu .reduce()i rozprzestrzenianiu się.

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

Zasadniczo tworzy nową tablicę z następnym elementem w foo i rozkłada zgromadzoną tablicę dla każdej iteracji po b.

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

Alternatywnie, .reduceRight()jak wspomniano powyżej, ale bez .push()mutacji.

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

4

Istnieje wiele sposobów odwracania tablicy bez modyfikacji. Dwie z nich są

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 wydajności http://jsben.ch/guftu


0

INTO zwykły JavaScript:

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

  return newArray;
}

0

Cofanie w miejscu z zamianą zmiennych tylko w celach demonstracyjnych (ale potrzebujesz kopii, jeśli nie chcesz mutować)

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

-4

es6:

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

4
Witamy w SO, Radion! Przy pozostawianiu odpowiedzi zazwyczaj dobrze jest wyjaśnić, dlaczego odpowiedź działa i dlaczego doszedłeś do tego wniosku, pomaga to nowym użytkownikom w zrozumieniu określonych przez Ciebie interakcji i języków.
— Ethan Field,

W obronie Radiona: P, że 1na końcu mogło być coś większego niż zero, ponieważ Array.prototype.sorttak compare functiondziała callback (lub tak zwany ). Zasadniczo zawsze porównujesz 2 liczby, w tym przypadku porównanie zawsze zwraca wartość dodatnią, więc zawsze mówi o przejściu do drugiej liczby przed pierwszą :) To bardzo objaśniające: stackoverflow.com/questions/6567941/…
— iulial

8
sort()mutuje tablicę (tzn. sortuje ją na miejscu), czego OP chce uniknąć.
— Clint Harris

5
Ta odpowiedź jest błędna na kilka sposobów. (1) mutuje tablicę, jak wskazuje @ClintHarris, więc nie jest lepsza niż .reverse (). (2) twój komparator jest nielegalny - gdy zwracasz 1 dla a, b, musisz zwrócić liczbę ujemną dla b, a. Jeśli twoja odpowiedź odwraca tablicę w niektórych implementacjach, dzieje się tak całkowicie przez szczęście.
— Don Hatch
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.