Membalikkan array dalam Javascript tanpa mengubah array asli

Jawaban:

377

Anda dapat menggunakan slice () untuk membuat salinan kemudian membalikkan () itu

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

Arun P Johny
sumber
Bisakah Anda jelaskan slice () tanpa parameter?
Alex
3
@Alex slice - If begin is omitted, slice begins from index 0.- jadi sama denganarray.slice(0)
Arun P Johny
2
Saya pikir @Alex berarti 'jelaskan dalam jawaban Anda' ... terlepas dari ... Solusi brilian. Terima kasih!
sfletche
14
Saya TIDAK akan merekomendasikan untuk menggunakan pendekatan ini, karena ini adalah praktik yang sangat menyesatkan. Ini sangat membingungkan ketika Anda menggunakan slice () dan Anda sebenarnya tidak mengiris apa pun. Jika Anda perlu membalikkan mundur, cukup buat salinan baru: const newArray = [... array] .reverse ()
Oleg Matei
105

Dalam ES6:

const newArray = [...array].reverse()
Brian M. Hunt
sumber
2
Bagaimana kinerja ini dibandingkan dengan jawaban yang diterima? Apakah mereka sama?
Katie
@ Katie Sangat mirip, keduanya sangat cepat, dengan Chrome tampaknya memberikan [...].reversekeunggulan dalam kasus uji yang sangat sederhana. jsperf.com/reverse-vs-slice-reverse/1
Brian M. Hunt
4
Saya secara konsisten mendapatkan .slicesecara signifikan lebih cepat.
James Coyle
3
@JamesCoyle Ini mungkin tergantung pada browser dan OS, tetapi slicekemungkinan lebih cepat b / c [...]adalah generik iterable-to-array sehingga tidak dapat membuat banyak asumsi. Juga, kemungkinan yang slicedioptimalkan lebih baik b / c sudah ada sejak lama.
Brian M. Hunt
Pikiranku persis.
James Coyle
11

Varian ES6 lainnya:

Kita juga bisa menggunakan .reduceRight()untuk membuat array terbalik tanpa benar-benar membalikkannya.

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

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

console.log(B);

Sumber Daya Berguna:

Mohammad Usman
sumber
2
reduceRightlambat af
Dragos Rizescu
@DragosRizescu Bisakah Anda membagikan beberapa hasil tes sampel?
Mohammad Usman
1
Berikut ini adalah repo yang dapat Anda mainkan: (bukan contoh terbaik, tetapi ada argumen ini dengan seseorang beberapa waktu lalu dalam konteks Bereaksi, jadi saya telah menggabungkannya): github.com/rizedr/reduce-vs-reduceRight
Dragos Rizescu
4
(a, c) => a.concat([c])terasa lebih idiomatis daripada(a, c) => (a.push(c), a)
Kyle Lin
1
@DragosRizescu sepertinya ini adalah yang tercepat dari 3 jawaban teratas. jsperf.com/reverse-vs-slice-reverse/3
DBosley
7

Coba solusi rekursif ini:

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
sumber
1
Sepertinya ini akan merusak array kosong.
Matthias
6

Alternatif ES6 menggunakan .reduce()dan menyebarkan.

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

Pada dasarnya yang dilakukannya adalah membuat array baru dengan elemen berikutnya di foo, dan menyebarkan array yang terakumulasi untuk setiap iterasi setelah b.

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

Atau .reduceRight()seperti yang disebutkan di atas di sini, tetapi tanpa .push()mutasi.

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

Ada beberapa cara membalikkan array tanpa mengubah. Dua di antaranya

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

Tes kinerja http://jsben.ch/guftu

shekhardtu
sumber
0

MENJADI Javascript biasa:

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

  return newArray;
}
Amit kumar
sumber
0

Membalikkan di tempat dengan variabel swap hanya untuk tujuan demonstratif (tetapi Anda memerlukan salinan jika Anda tidak ingin bermutasi)

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

es6:

const reverseArr = [1,2,3,4].sort(()=>1)
Radion Ponomarenko
sumber
4
Selamat datang di SO, Radion! Ketika meninggalkan jawaban, biasanya ide yang bagus untuk menjelaskan mengapa jawaban Anda bekerja dan mengapa Anda sampai pada kesimpulan ini, ini membantu pengguna yang lebih baru dengan memahami interaksi dan bahasa yang telah Anda tentukan.
Lapangan Etan
Dalam pembelaan Radion: P yang 1pada akhirnya bisa saja lebih besar dari nol, karena itulah cara kerja Array.prototype.sortcallback (atau disebut demikian compare function). Pada dasarnya Anda selalu membandingkan 2 angka dan dalam hal ini pengembalian kembali selalu positif sehingga dikatakan selalu pindah ke angka kedua di depan yang pertama :) ini sangat jelas: stackoverflow.com/questions/6567941/…
iulial
8
sort()bermutasi array (yaitu, mengurutkannya di tempat), yang ingin menghindari OP.
Clint Harris
5
Jawaban ini salah dalam beberapa hal. (1) itu memutasi array, seperti yang ditunjukkan oleh @ClintHarris, jadi tidak lebih baik dari .reverse (). (2) pembanding Anda ilegal-- ketika Anda mengembalikan 1 untuk a, b, Anda harus mengembalikan angka negatif untuk b, a. Jika jawaban Anda membalikkan array pada beberapa implementasi, itu sepenuhnya karena keberuntungan.
Don Hatch