Saya mengalami kesulitan mencari tahu cara memindahkan elemen array. Misalnya, diberikan yang berikut ini:
var arr = [ 'a', 'b', 'c', 'd', 'e'];
Bagaimana saya bisa menulis fungsi untuk dipindahkan 'd'
sebelumnya 'b'
?
Atau 'a'
setelah 'c'
?
Setelah pindah, indeks elemen lainnya harus diperbarui. Ini berarti dalam contoh pertama setelah langkah arr [0] akan = 'a', arr [1] = 'd' arr [2] = 'b', arr [3] = 'c', arr [4] = 'e'
Ini sepertinya cukup sederhana, tapi aku tidak bisa membungkus kepalaku.
javascript
arrays
Mark Brown
sumber
sumber
const changeValuePosition = (arr, init, target) => {[arr[init],arr[target]] = [arr[target],arr[init]]; return arr}
init
dantarget
.Jawaban:
Jika Anda menginginkan versi pada npm, array-move adalah yang paling dekat dengan jawaban ini, walaupun itu bukan implementasi yang sama. Lihat bagian penggunaannya untuk lebih jelasnya. Versi sebelumnya dari jawaban ini (yang memodifikasi Array.prototype.move) dapat ditemukan pada npm di array.prototype.move .
Saya cukup sukses dengan fungsi ini:
Perhatikan bahwa yang terakhir
return
hanya untuk tujuan pengujian:splice
melakukan operasi pada array di tempat, sehingga pengembalian tidak diperlukan. Selain itu, inimove
adalah operasi di tempat. Jika Anda ingin menghindari itu dan mengembalikan salinan, gunakanslice
.Melangkah menelusuri kode:
new_index
lebih besar dari panjang array, kami ingin (saya kira) untuk mengisi array dengan benar dengan yang baruundefined
. Cuplikan kecil ini menangani ini dengan menekanundefined
array sampai kita memiliki panjang yang sesuai.arr.splice(old_index, 1)[0]
, kita membelah elemen lama.splice
mengembalikan elemen yang disambungkan, tetapi dalam array. Dalam contoh kami di atas, ini[1]
. Jadi kami mengambil indeks pertama array itu untuk mendapatkan yang mentah di1
sana.splice
untuk memasukkan elemen ini di tempat new_index. Karena kami mengisi array di atas jikanew_index > arr.length
, mungkin akan muncul di tempat yang tepat, kecuali jika mereka telah melakukan sesuatu yang aneh seperti memasukkan angka negatif.Versi yang lebih menarik untuk memperhitungkan indeks negatif:
Yang seharusnya menjelaskan hal-hal seperti
array_move([1, 2, 3], -1, -2)
dengan benar (pindahkan elemen terakhir ke tempat kedua ke tempat terakhir). Hasil untuk itu seharusnya[1, 3, 2]
.Either way, dalam pertanyaan asli Anda, Anda akan melakukan
array_move(arr, 0, 2)
untuka
setelahc
. Untukd
sebelumnyab
, Anda akan melakukannyaarray_move(arr, 3, 1)
.sumber
.hasOwnProperty
centang ketika mengulangi hal-hal seperti untuk..di, terutama dengan pustaka seperti Prototipe dan MooTools yang memodifikasi prototipe. Bagaimanapun, saya tidak merasa itu adalah masalah yang sangat penting dalam contoh yang relatif terbatas seperti ini, dan ada perpecahan yang bagus di komunitas mengenai apakah modifikasi prototipe adalah ide yang baik atau tidak. Namun, biasanya masalah iterasi adalah yang paling tidak diperhatikan.this[new_index] = undefined;
dalamif
blok. Karena array Javascript jarang, ini akan memperluas ukuran array untuk memasukkan new_index.splice
agar berfungsi tetapi tanpa perlu membuat elemen apa pun yang campur tangan.this[new_index] = undefined
akan benar-benar menempatkanundefined
slot array sebelum indeks yang benar. (Misalnya,[1,2,3].move(0,10)
akan ada1
di slot 10 danundefined
di slot 9.) Sebaliknya, jika sparseness baik-baik saja, kita bisa melakukannyathis[new_index] = this.splice(old_index, 1)[0]
tanpa panggilan splice lainnya (sebagai gantinya / kalau bukan).Inilah satu liner yang saya temukan di JSPerf ....
yang mengagumkan untuk dibaca, tetapi jika Anda ingin kinerja (dalam set data kecil) coba ...
Saya tidak bisa mengambil kredit apa pun, itu semua harus ke Richard Scarrott . Ini mengalahkan metode berbasis sambatan untuk set data yang lebih kecil dalam tes kinerja ini . Namun secara signifikan lebih lambat pada set data yang lebih besar seperti yang ditunjukkan Darwayne .
sumber
from >= to ? this.splice(to, 0, this.splice(from, 1)[0]) : this.splice(to - 1, 0, this.splice(from, 1)[0]);
Saya suka cara ini. Ini ringkas dan berhasil.
Catatan: selalu ingat untuk memeriksa batas array Anda.
Jalankan Cuplikan di jsFiddle
sumber
karena fungsi ini dapat dihubungkan, ini juga berfungsi:
demo di sini
sumber
2c saya Mudah dibaca, bekerja, cepat, tidak membuat array baru.
sumber
array
, seperti yang dilakukan di akhir.Mendapat ide ini dari @ Reid mendorong sesuatu di tempat item yang seharusnya dipindahkan untuk menjaga ukuran array konstan. Itu memang menyederhanakan perhitungan. Juga, mendorong objek kosong memiliki manfaat tambahan karena dapat mencarinya secara unik nanti. Ini berfungsi karena dua objek tidak sama sampai mereka merujuk ke objek yang sama.
Jadi, inilah fungsi yang mengambil dalam array sumber, dan sumber, indeks tujuan. Anda dapat menambahkannya ke Array.prototype jika diperlukan.
sumber
sourceIndex = 0
,destIndex = 1
destIndex
dimaksudkan sebagai indeks sebelum elemen sumber dipindahkan dalam array.Ini didasarkan pada solusi @ Reid. Kecuali:
Array
prototipe.undefined
item, itu hanya memindahkan item ke posisi paling kanan.Fungsi:
Tes unit:
sumber
Berikut ini adalah solusi ES6 one liner saya dengan parameter opsional
on
.Adaptasi solusi pertama yang diusulkan oleh
digiguru
Parameter
on
adalah jumlah elemen mulai darifrom
yang ingin Anda pindahkan.sumber
The
splice
metodeArray
kekuatan bantuan: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/spliceHanya perlu diingat bahwa itu mungkin relatif mahal karena harus secara aktif mengindeks ulang array.
sumber
Salah satu pendekatan akan membuat array baru dengan potongan-potongan dalam urutan yang Anda inginkan, menggunakan metode slice.
Contoh
sumber
arr2
akhirnya Anda adalah sebuah string karena operasi penggabungan, kan? :) Akhirnya menjadi"adc,de"
.Anda dapat menerapkan beberapa Kalkulus dasar dan membuat fungsi universal untuk memindahkan elemen array dari satu posisi ke posisi lain.
Untuk JavaScript tampilannya seperti ini:
Lihat "elemen array yang bergerak" di "gloommatter" untuk penjelasan terperinci.
http://www.gloommatter.com/DDesign/programming/moving-any-array-elements-universal-function.html
sumber
Saya telah menerapkan
ECMAScript 6
solusi yang tidak dapat diubah berdasarkan dari@Merc
jawaban di sini:Nama-nama variabel dapat disingkat, hanya digunakan yang panjang sehingga kode dapat menjelaskan sendiri.
sumber
array
segera kembali jikafromIndex === toIndex
, dan hanya membuatnewArray
jika tidak demikian? Kekekalan tidak berarti bahwa satu salinan baru harus dibuat per panggilan fungsi bahkan ketika tidak ada perubahan. Hanya meminta b / c motif untuk peningkatan panjang fungsi ini (relatif terhadap one-liner berbasis splice) adalah kinerja, danfromIndex
mungkin sering samatoIndex
, tergantung pada penggunaan.Saya membutuhkan metode bergerak yang tidak berubah (yang tidak mengubah array asli), jadi saya mengadaptasi jawaban yang diterima @ Reid untuk hanya menggunakan Object.assign untuk membuat salinan array sebelum melakukan sambungan.
Berikut adalah jsfiddle yang menunjukkannya dalam aksi .
sumber
http://plnkr.co/edit/JaiAaO7FQcdPGPY6G337?p=preview
sumber
Saya akhirnya menggabungkan dua ini untuk bekerja sedikit lebih baik ketika memindahkan jarak kecil dan besar. Saya mendapatkan hasil yang cukup konsisten, tetapi ini mungkin bisa sedikit diubah oleh seseorang yang lebih pintar daripada saya untuk bekerja secara berbeda untuk ukuran yang berbeda, dll.
Menggunakan beberapa metode lain saat memindahkan objek jarak kecil secara signifikan lebih cepat (x10) daripada menggunakan sambungan. Ini mungkin berubah tergantung pada panjang array, tetapi itu berlaku untuk array besar.
http://jsperf.com/arraymove-many-sizes
sumber
Ini dinyatakan di banyak tempat ( menambahkan fungsi kustom ke dalam Array.prototype ) bermain dengan prototipe Array bisa menjadi ide yang buruk, toh saya menggabungkan yang terbaik dari berbagai posting, saya datang dengan ini, menggunakan Javascript modern:
Semoga bisa bermanfaat bagi siapa saja
sumber
Versi ini tidak ideal untuk semua tujuan, dan tidak semua orang suka ekspresi koma, tapi ini satu-liner yang merupakan ekspresi murni, membuat salinan baru:
Versi yang sedikit ditingkatkan kinerja akan mengembalikan array input jika tidak diperlukan langkah apa pun, itu masih OK untuk penggunaan yang tidak dapat diubah, karena array tidak akan berubah, dan itu masih ekspresi murni:
Doa keduanya adalah
yaitu mengandalkan penyebaran untuk menghasilkan salinan baru. Menggunakan arity tetap 3
move
akan membahayakan properti ekspresi tunggal, atau sifat non-destruktif, atau manfaat kinerjasplice
. Sekali lagi, ini lebih merupakan contoh yang memenuhi beberapa kriteria daripada saran untuk penggunaan produksi.sumber
Array.move.js
Ringkasan
Memindahkan elemen dalam array, mengembalikan array yang mengandung elemen yang dipindahkan.
Sintaksis
Parameter
index : Indeks tempat memindahkan elemen. Jika negatif, indeks akan mulai dari akhir.
howMany : Jumlah elemen untuk dipindahkan dari indeks .
toIndex : Indeks array tempat menempatkan elemen yang dipindahkan. Jika negatif, toIndex akan mulai dari akhir.
Pemakaian
Polyfill
sumber
.move
sepertinya itu harus bekerja (saya belum mengujinya), Anda harus mencatat bahwa itu bukan bagian dari standar apa pun. Ini juga baik untuk memperingatkan orang-orang bahwa fungsi polyfill / monkeypatched dapat memecahkan beberapa kode yang menganggap semua yang dapat dihitung adalah milik mereka.Saya menggunakan jawaban yang bagus dari @Reid , tetapi berjuang dengan memindahkan elemen dari akhir array satu langkah lebih jauh - ke awal (seperti dalam satu lingkaran ). Misalnya ['a', 'b', 'c'] harus menjadi ['c', 'a', 'b'] dengan memanggil .move (2,3)
Saya mencapai ini dengan mengubah case untuk new_index> = this.length.
sumber
Sebagai tambahan untuk jawaban luar biasa Reid (dan karena saya tidak bisa berkomentar); Anda dapat menggunakan modulo untuk membuat indeks negatif dan terlalu besar "berguling":
sumber
sumber
Saya pikir ini masalah swap tetapi tidak. Inilah solusi satu-liner saya:
Inilah tes kecil:
sumber
hasil:
sumber
sumber
sumber
Versi tidak berubah tanpa salinan array:
sumber
Saya pikir cara terbaik adalah mendefinisikan properti baru untuk Array
sumber
Varian JS murni lainnya menggunakan operator spread array ES6 tanpa mutasi
sumber
Metode ini akan mempertahankan array asli, dan memeriksa kesalahan pembatas.
sumber