Saya mencoba mencari cara untuk memeriksa keberadaan suatu nilai dalam array tanpa iterasi melalui array.
Saya membaca file sebagai parameter. Saya memiliki daftar panjang parameter yang tidak ingin saya tangani. Saya menempatkan parameter yang tidak diinginkan ini dalam sebuah array @badparams
.
Saya ingin membaca parameter baru dan jika tidak ada @badparams
, proseskan. Jika ada @badparams
, buka bacaan berikutnya.
perl
arrays
comparison
Mel
sumber
sumber
Jawaban:
Cukup ubah array menjadi hash:
Anda juga dapat menambahkan lebih banyak params (unik) ke daftar:
Dan kemudian dapatkan daftar params (unik) kembali:
sumber
1
lagi.Tujuan umum terbaik - Terutama array pendek (1000 item atau kurang) dan coders yang tidak yakin tentang optimasi apa yang paling sesuai dengan kebutuhan mereka.
Telah disebutkan bahwa grep melewati semua nilai bahkan jika nilai pertama dalam array cocok. Ini benar, namun grep masih sangat cepat untuk sebagian besar kasus . Jika Anda berbicara tentang array pendek (kurang dari 1000 item) maka sebagian besar algoritma akan menjadi sangat cepat. Jika Anda berbicara tentang array yang sangat panjang (1.000.000 item), grep dapat diterima dengan cepat terlepas dari apakah item tersebut adalah yang pertama atau tengah atau terakhir dalam array.
Kasus Optimasi untuk array yang lebih panjang:
Jika array Anda diurutkan , gunakan "pencarian biner".
Jika array yang sama berulang kali dicari berkali-kali, salin ke hash dulu dan kemudian periksa hash. Jika memori menjadi masalah, maka pindahkan setiap item dari array ke hash. Lebih banyak memori efisien tetapi menghancurkan array asli.
Jika nilai yang sama dicari berulang kali dalam array, malas buat cache. (karena setiap item dicari, periksa terlebih dahulu apakah hasil pencarian disimpan dalam hash tetap. Jika hasil pencarian tidak ditemukan dalam hash, lalu cari array dan masukkan hasilnya dalam hash persisten sehingga waktu berikutnya kita akan temukan di hash dan lewati pencarian).
Catatan: optimasi ini hanya akan lebih cepat ketika berhadapan dengan array panjang. Jangan terlalu mengoptimalkan.
sumber
Anda dapat menggunakan fitur smartmatch di Perl 5.10 sebagai berikut:
Untuk melakukan pencarian nilai literal, lakukan di bawah ini.
Untuk pencarian skalar, melakukan di bawah ini akan berfungsi seperti di atas.
Untuk melakukan inline array di bawah ini, akan berfungsi seperti di atas.
Dalam Perl 5.18 smartmatch ditandai sebagai percobaan karena itu Anda perlu mematikan peringatan dengan menyalakan pragma eksperimental dengan menambahkan di bawah ini ke skrip / modul Anda:
Atau jika Anda ingin menghindari penggunaan smartmatch - maka seperti kata Aaron gunakan:
sumber
use experimental 'smartmatch'
direkomendasikan. Karena saya memiliki kendali atas versi perl saya (sistem internal), saya menggunakanno warnings 'experimental::smartmatch';
pernyataan itu.Posting blog ini membahas jawaban terbaik untuk pertanyaan ini.
Sebagai ringkasan singkat, jika Anda dapat menginstal modul CPAN maka solusi yang paling mudah dibaca adalah:
atau
Namun, ungkapan yang lebih umum adalah:
Tapi tolong jangan gunakan
first()
fungsinya! Itu sama sekali tidak mengungkapkan maksud kode Anda. Jangan gunakan~~
operator "Pencocokan pintar": itu rusak. Dan jangan gunakangrep()
atau solusi dengan hash: mereka beralih melalui seluruh daftar.any()
akan berhenti segera setelah menemukan nilai Anda.Lihat posting blog untuk lebih jelasnya.
sumber
use List::Util qw(any);
.List::Util
ada dalam modul Core .Metode 1: grep (mungkin hati-hati sementara nilai diharapkan menjadi regex).
Cobalah untuk menghindari penggunaan
grep
, jika melihat sumber daya.Metode 2: Pencarian Linier
Metode 3: Gunakan hash
Metode 4: smartmatch
(ditambahkan dalam Perl 5.10, ditandai adalah eksperimental dalam Perl 5.18).
Metode 5: Gunakan modul
List::MoreUtils
sumber
Patokan @ eakssjo rusak - langkah-langkah membuat hash di loop vs membuat regexes di loop. Versi tetap (ditambah saya telah menambahkan
List::Util::first
danList::MoreUtils::any
):Dan hasilnya (ini untuk iterasi 100_000, sepuluh kali lebih banyak dari pada jawaban @ eakssjo):
sumber
Meskipun nyaman digunakan, sepertinya solusi konversi-ke-hash memerlukan cukup banyak kinerja, yang merupakan masalah bagi saya.
Output dari tes benchmark:
sumber
List::Util::first
lebih cepat karena berhenti iterasi ketika menemukan kecocokan.grep
adalah signifikan lebih lambat dari menciptakan hash dan melakukan pencarian, sejak mantan adalah O (n) dan yang terakhir O (1). Lakukan saja pembuatan hash hanya sekali (di luar loop) dan precompute regex untuk mengukur metode saja ( lihat jawaban saya ).@files adalah array yang ada
/^2[\d[.[\d[[A-za-z[?/ = vaues mulai dari 2 di sini Anda dapat menaruh ekspresi reguler apa pun
sumber
Anda tentu menginginkan hash di sini. Tempatkan parameter buruk sebagai kunci dalam hash, lalu putuskan apakah parameter tertentu ada di hash.
Jika Anda benar-benar tertarik melakukannya dengan array, lihat
List::Util
atauList::MoreUtils
sumber
Ada dua cara Anda bisa melakukan ini. Anda bisa menggunakan lemparan nilai ke dalam hash untuk tabel pencarian, seperti yang disarankan oleh posting lain. (Saya hanya akan menambahkan idiom lain.)
Tetapi jika data sebagian besar karakter kata dan tidak terlalu banyak meta, Anda dapat membuangnya ke dalam pergantian regex:
Solusi ini harus disesuaikan dengan jenis "nilai buruk" yang Anda cari. Dan lagi, itu mungkin sama sekali tidak pantas untuk jenis string tertentu, jadi emptor peringatan .
sumber
@bad_param_lookup{@bad_params} = ()
, tetapi Anda harus menggunakannyaexists
untuk menguji keanggotaan.Anda mungkin ingin memeriksa konsistensi spasial numerik terkemuka
sumber