Saya memiliki sejumlah angka yang harus saya pastikan unik. Saya menemukan potongan kode di bawah di internet dan berfungsi dengan baik sampai array memiliki nol di dalamnya. Saya menemukan skrip lain di sini di Stack Overflow yang terlihat hampir persis seperti itu, tetapi tidak gagal.
Jadi demi membantu saya belajar, dapatkah seseorang membantu saya menentukan di mana skrip prototipe salah?
Array.prototype.getUnique = function() {
var o = {}, a = [], i, e;
for (i = 0; e = this[i]; i++) {o[e] = 1};
for (e in o) {a.push (e)};
return a;
}
Jawaban lain dari pertanyaan rangkap:
Pertanyaan serupa:
javascript
arrays
unique
Mottie
sumber
sumber
o
=object
,a
=array
,i
=index
dane
= umm, sesuatu: PJawaban:
Dengan JavaScript 1.6 / ECMAScript 5 Anda dapat menggunakan
filter
metode asli dari Array dengan cara berikut untuk mendapatkan array dengan nilai unik:Metode asli
filter
akan mengulang melalui array dan hanya menyisakan entri yang melewati fungsi callback yang diberikanonlyUnique
.onlyUnique
memeriksa, jika nilai yang diberikan adalah yang pertama kali terjadi. Jika tidak, itu harus duplikat dan tidak akan disalin.Solusi ini berfungsi tanpa pustaka tambahan seperti jQuery atau prototype.js.
Ini berfungsi untuk array dengan tipe nilai campuran juga.
Untuk Browser lama (<ie9), yang tidak mendukung metode asli
filter
danindexOf
Anda dapat menemukan pekerjaan di dokumentasi MDN untuk filter dan indexOf .Jika Anda ingin mempertahankan kemunculan nilai terakhir, gantikan
indexOf
denganlastIndexOf
.Dengan ES6 bisa disingkat menjadi ini:
Terima kasih kepada Camilo Martin untuk petunjuk dalam komentar.
ES6 memiliki objek asli
Set
untuk menyimpan nilai unik. Untuk mendapatkan array dengan nilai unik yang dapat Anda lakukan sekarang ini:Konstruktor
Set
mengambil objek yang dapat...
diubah , seperti Array, dan operator spread mengubah set kembali menjadi Array. Terima kasih kepada Lukas Liese untuk petunjuk dalam komentar.sumber
['a', 1, 'a', 2, '1']
Anda akan mendapatkan['a', 1, 2]
. Tapi ini bukan yang saya harapkan. BTW, jauh lebih lambat sangat relatif..filter((v,i,a)=>a.indexOf(v)==i)
(notasi panah gemuk).let unique_values = [...new Set(random_array)];
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Diperbarui jawaban untuk ES6 / ES2015 : Menggunakan Set , solusi garis tunggal adalah:
Yang kembali
Seperti yang disarankan le_m , ini juga dapat disingkat menggunakan operator spread , seperti
sumber
Array.from(new Set([[1,2],[1,2],[1,2,3]]))
myArray.filter((v, i, a) => a.indexOf(v) === i);
?Set
dan menambahkan objek alih-alih nilai primitif itu akan berisi referensi unik ke objek. Dengan demikian sets
inlet s = new Set([{Foo:"Bar"}, {Foo:"Bar"}]);
akan mengembalikan ini:Set { { Foo: 'Bar' }, { Foo: 'Bar' } }
yang merupakanSet
referensi objek unik ke objek yang berisi nilai yang sama. Jika Anda menulislet o = {Foo:"Bar"};
dan kemudian membuat satu set dengan dua referensi sepertilet s2 = new Set([o,o]);
Set { { Foo: 'Bar' } }
new Set
trofiSaya menyadari pertanyaan ini sudah memiliki lebih dari 30 jawaban. Tetapi saya sudah membaca semua jawaban yang ada terlebih dahulu dan melakukan penelitian sendiri.
Saya membagi semua jawaban ke 4 solusi yang mungkin:
[...new Set( [1, 1, 2] )];
{ }
untuk mencegah duplikat[ ]
filter + indexOf
Berikut kode contoh yang ditemukan dalam jawaban:
Gunakan fitur ES6 baru:
[...new Set( [1, 1, 2] )];
Gunakan objek
{ }
untuk mencegah duplikatGunakan array pembantu
[ ]
Menggunakan
filter + indexOf
Dan saya bertanya-tanya mana yang lebih cepat. Saya telah membuat sampel Google Sheet untuk menguji fungsi. Catatan: ECMA 6 tidak tersedia di Google Sheets, jadi saya tidak bisa mengujinya.
Inilah hasil tes:
Saya berharap melihat bahwa kode yang menggunakan objek
{ }
akan menang karena menggunakan hash. Jadi saya senang bahwa tes menunjukkan hasil terbaik untuk algoritma ini di Chrome dan IE. Terima kasih kepada @rab untuk kodenya .sumber
Anda juga dapat menggunakan underscore.js .
yang akan kembali:
sumber
array = [...new Set(array)]
Satu Liner, JavaScript Murni
Dengan sintaks ES6
list = list.filter((x, i, a) => a.indexOf(x) == i)
Dengan sintaks ES5
Kompatibilitas Browser : IE9 +
sumber
Saya telah menemukan metode bagus yang menggunakan jQuery
Catatan: Kode ini diambil dari pos tinju bebek Paul Irish - Saya lupa memberi kredit: P
sumber
Solusi terpendek dengan ES6:
[...new Set( [1, 1, 2] )];
Atau jika Anda ingin memodifikasi prototipe Array (seperti pada pertanyaan awal):
EcmaScript 6 hanya sebagian diimplementasikan di browser modern saat ini (Agustus 2015), tetapi Babel telah menjadi sangat populer untuk mentransformasikan ES6 (dan bahkan ES7) kembali ke ES5. Dengan begitu Anda dapat menulis kode ES6 hari ini!
Jika Anda bertanya-tanya apa
...
artinya, itu disebut operator penyebaran . Dari MDN : «Operator spread memungkinkan ekspresi diperluas di tempat-tempat di mana banyak argumen (untuk panggilan fungsi) atau beberapa elemen (untuk literal array) diharapkan». Karena Set adalah iterable (dan hanya dapat memiliki nilai unik), operator spread akan memperluas Set untuk mengisi array.Sumber daya untuk belajar ES6:
sumber
a = [...Set(a)]
, tetapi, bagaimanapun, ini hanya Firefox, untuk saat ini.require ( "core-js/fn/array/from" );
[...Set(['a', 1, 'a', 2, '1'])]
akan melemparkan TypeError, jadi masih bijaksana untuk mempertahankannew
:[...new Set(['a', 1, 'a', 2, '1'])]
Solusi paling sederhana:
Atau:
sumber
Cara paling sederhana, dan tercepat (di Chrome) untuk melakukan ini:
Cukup menelusuri setiap item dalam array, menguji apakah item itu sudah ada dalam daftar, dan jika tidak, dorong ke array yang akan dikembalikan.
Menurut jsPerf, fungsi ini adalah yang tercepat yang bisa saya temukan di mana saja - silakan menambahkan sendiri.
Versi non-prototipe:
Penyortiran
Ketika juga perlu mengurutkan array, berikut ini adalah yang tercepat:
atau non-prototipe:
Ini juga lebih cepat daripada metode di atas di sebagian besar browser non-chrome.
sumber
unique
fungsi memiliki kompleksitas O (n ^ 2) sementara yang digetUnique
dalamnya adalah O (n). Yang pertama mungkin lebih cepat pada set data kecil, tetapi bagaimana Anda bisa berdebat dengan matematika :) Anda dapat memastikan yang terakhir lebih cepat jika Anda menjalankannya pada array, katakanlah, 1e5 item unikHANYA KINERJA! kode ini mungkin 10X lebih cepat dari semua kode di sini * berfungsi pada semua browser dan juga memiliki dampak memori terendah .... dan banyak lagi
jika Anda tidak perlu menggunakan kembali larik lama; btw lakukan operasi lain yang diperlukan sebelum mengubahnya menjadi unik di sini mungkin cara tercepat untuk melakukan ini, juga sangat singkat.
maka kamu bisa mencoba ini
Saya datang dengan fungsi ini membaca artikel ini ...
http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/
Saya tidak suka for loop. ia memiliki banyak parameter. saya suka loop while--. sedangkan loop tercepat di semua browser kecuali yang kita semua sangat suka ... chrome.
Lagi pula saya menulis fungsi pertama yang menggunakan while. Dan ya itu sedikit lebih cepat daripada fungsi yang ditemukan dalam artikel.tapi tidak cukup.
unique2()
langkah selanjutnya gunakan js modern.
Object.keys
saya mengganti yang lain untuk loop dengan Object.keys js1.7 ... sedikit lebih cepat dan lebih pendek (di krom 2x lebih cepat);). Tidak cukup!.unique3()
.pada titik ini saya sedang berpikir tentang apa yang sebenarnya saya butuhkan dalam fungsi unik SAYA. saya tidak memerlukan array lama, saya ingin fungsi cepat. jadi saya menggunakan 2 saat loop + sambatan.
unique4()
Tidak ada gunanya mengatakan bahwa saya terkesan.
chrome: 150.000 operasi per detik yang biasa melonjak menjadi 1.800.000 operasi per detik.
yaitu: 80.000 op / s vs 3.500.000 op / s
ios: 18.000 op / s vs 170.000 op / s
safari: 80.000 op / s vs 6.000.000 op / s
Bukti http://jsperf.com/wgu atau lebih baik gunakan console.time ... microtime ... terserah
unique5()
hanya untuk menunjukkan kepada Anda apa yang terjadi jika Anda ingin mempertahankan array yang lama.Jangan gunakan
Array.prototype
jika kamu tidak tahu apa yang kamu lakukan. Saya hanya melakukan banyak salinan dan masa lalu. GunakanObject.defineProperty(Array.prototype,...,writable:false,enumerable:false})
jika Anda ingin membuat prototipe asli.contoh: https://stackoverflow.com/a/20463021/2450730Demo http://jsfiddle.net/46S7g/
CATATAN: array lama Anda hancur / menjadi unik setelah operasi ini.
jika Anda tidak dapat membaca kode di atas tanyakan, baca buku javascript atau di sini ada beberapa penjelasan tentang kode pendek. https://stackoverflow.com/a/21353032/2450730
beberapa menggunakan
indexOf
... jangan ... http://jsperf.com/dgfgghfghfghghgfhgfhfghfhgfhuntuk array kosong
sumber
Banyak jawaban di sini mungkin tidak berguna untuk pemula. Jika menghapus duplikat array sulit, apakah mereka benar-benar tahu tentang rantai prototipe, atau bahkan jQuery?
Di browser modern, solusi bersih dan sederhana adalah menyimpan data dalam Set , yang dirancang untuk menjadi daftar nilai unik.
Ini
Array.from
berguna untuk mengonversi Set kembali ke Array sehingga Anda memiliki akses mudah ke semua metode (fitur) mengagumkan yang dimiliki array. Ada juga cara lain untuk melakukan hal yang sama. Tetapi Anda mungkin tidak perluArray.from
sama sekali, karena Sets memiliki banyak fitur berguna seperti forEach .Jika Anda perlu mendukung Internet Explorer lama, dan dengan demikian tidak dapat menggunakan Set, maka teknik sederhana adalah menyalin item ke array baru sambil memeriksa sebelumnya apakah mereka sudah ada dalam array baru.
Untuk membuat ini dapat digunakan kembali secara instan, mari kita fungsi.
Jadi untuk menghilangkan duplikat, sekarang kita akan melakukan ini.
The
deduplicate(cars)
bagian menjadi hal yang kami beri nama hasil ketika selesai fungsi.Berikan nama array yang Anda suka.
sumber
sumber
push
elemen ke array daripada menggunakanconcat
? Saya mencoba menggunakan push dan gagal. Saya mencari penjelasan.[0,1,2,0,3,2,1,5].reduce((prev, cur) => ~prev.indexOf(cur) ? prev : prev.concat([cur]), []);
NaN
-ramahKita bisa melakukan ini menggunakan set ES6:
// Keluarannya adalah
sumber
Prototipe
getUnique
ini tidak sepenuhnya benar, karena jika saya memiliki array seperti:["1",1,2,3,4,1,"foo"]
itu akan kembali["1","2","3","4"]
dan"1"
adalah string dan1
merupakan bilangan bulat; mereka berbeda.Inilah solusi yang benar:
menggunakan:
Di atas akan menghasilkan
["1",2,3,4,1,"foo"]
.sumber
$foo = 'bar'
ini adalah cara PHP untuk mendeklarasikan variabel. Ini akan bekerja dalam javascript, tetapi akan membuat global tersirat, dan umumnya tidak boleh dilakukan.$foo
adalah cara mendeklarasikan variabel dalam javascript sementara sebenarnyavar foo
.Tanpa memperluas Array.prototype (dikatakan praktik yang buruk) atau menggunakan jquery / garis bawah, Anda dapat dengan mudah
filter
menggunakan array.Dengan menjaga kejadian terakhir:
atau kejadian pertama:
Yah, ini hanya javascript ECMAScript 5+, yang berarti hanya IE9 +, tapi bagus untuk pengembangan HTML / JS asli (Aplikasi Windows Store, Firefox OS, Sencha, Phonegap, Titanium, ...).
sumber
filter
. Di halaman MDN mereka memiliki implementasi untuk Internet Explorer, maksud saya, browser yang lebih lama. Juga: JS 1.6 hanya merujuk ke mesin js Firefox, tetapi hal yang benar untuk mengatakan itu adalah ECMAScript 5.Sihir
O (n) kinerja ; kami menganggap array Anda ada di
a
dant={}
. Penjelasan di sini (+ Jeppe impr.)Tampilkan cuplikan kode
sumber
in
operator di luar konstruksi selainfor
loop: P) - Terima kasih - Saya menghargai itu dan akan memberikan +2 untuk jawaban Anda yang baik lainnya .t
yang tetap hidup setelah pemfilteran ... ??sumber
Jika Anda menggunakan kerangka kerja Prototipe tidak perlu melakukan loop 'for', Anda dapat menggunakan http://www.prototypejs.org/api/array/uniq seperti ini:
Yang akan menghasilkan array duplikat tanpa duplikat. Saya menemukan pertanyaan Anda mencari metode untuk menghitung catatan array yang berbeda
Saya menggunakan
dan ada hasil sederhana saya. ps Maaf jika saya salah menuliskan sesuatu
sunting: jika Anda ingin lepas dari catatan yang tidak ditentukan, Anda mungkin ingin menambahkan
sebelumnya, seperti ini:
sumber
Sekarang menggunakan set Anda dapat menghapus duplikat dan mengubahnya kembali ke array.
Solusi lain adalah dengan menggunakan sort & filter
sumber
Itu karena
0
merupakan nilai palsu dalam JavaScript.this[i]
akan menjadi falsy jika nilai array adalah 0 atau nilai falsy lainnya.sumber
sumber
o
bukan hanya a1
, meskipun perbandingan kesetaraan masih akan menjadi stringwise (meskipun, dari semua kemungkinan persamaan Javascript, sepertinya tidak terlalu tidak masuk akal).Saya punya masalah yang sedikit berbeda di mana saya perlu menghapus objek dengan duplikat properti id dari sebuah array. ini berhasil.
sumber
Jawaban paling sederhana adalah:
sumber
Saya tidak yakin mengapa Gabriel Silveira menulis fungsi seperti itu tetapi bentuk yang lebih sederhana yang bekerja untuk saya dengan baik dan tanpa minifikasi adalah:
atau dalam CoffeeScript:
sumber
Jika Anda baik-baik saja dengan dependensi tambahan, atau Anda sudah memiliki salah satu perpustakaan di basis kode Anda, Anda dapat menghapus duplikat dari array di tempat menggunakan LoDash (atau Underscore).
Pemakaian
Jika Anda belum memilikinya di basis kode, instal menggunakan npm:
Kemudian gunakan sebagai berikut:
Di luar:
sumber
Ini telah dijawab banyak, tetapi tidak menjawab kebutuhan khusus saya.
Banyak jawaban seperti ini:
Tapi ini tidak berfungsi untuk array objek kompleks.
Katakanlah kita memiliki array seperti ini:
Jika kita menginginkan objek dengan nama unik, kita harus menggunakan
array.prototype.findIndex
alih-aliharray.prototype.indexOf
:sumber
Dari kompleksitas waktu blog Shamasis Bhattacharya (O (2n)):
Dari blog Paul Irish : peningkatan pada JQuery
.unique()
:sumber
Menemukan nilai Array unik dalam metode sederhana
sumber
Tampaknya kami telah kehilangan jawaban Rafael , yang berdiri sebagai jawaban yang diterima selama beberapa tahun. Ini (setidaknya di 2017) solusi berkinerja terbaik jika Anda tidak memiliki array tipe campuran :
Jika Anda memang memiliki array tipe campuran, Anda bisa membuat serialisasi kunci hash:
sumber
Untuk mengatasi masalah sebaliknya, mungkin berguna untuk tidak memiliki duplikat saat Anda memuat array Anda, cara Set objek akan melakukannya tetapi itu belum tersedia di semua browser. Menghemat memori dan lebih efisien jika Anda perlu melihat isinya berkali-kali.
Sampel:
Memberi anda
set = [1,3,4,2]
sumber