objek id javascript js - Cara cepat untuk menemukan string dalam array

Bentuk interaksi pengguna akan sama seperti pada Listing 3.15. Mari kita ubah fungsinya (Listing 3.17). Kali ini array nilai integer akan diberikan. Penting untuk memeriksa nomor yang dimasukkan oleh pengguna dengan nilai yang dicatat dalam array. Jika terjadi kecocokan, Anda perlu mengeluarkannya nomor seri elemen. Jika kecocokan tidak terjadi, pesan kesalahan harus ditampilkan.

Daftar 3.17. File Myscript.js - Pencarian Array

  • var susunan = ;
  • $("#ok").klik(fungsi() (
  • var objek = parseInt($("#string").val());
  • var jawaban = $.inArray(objek, array);
  • if (answer == "-1") alert("Array [" +array + "]. Nilai "+object+ " tidak ada dalam array");
  • else alert("Array [" +array + "]. Nilai " + objek + " di bawah angka " + jawaban)
  • });
  • });
  • Pada Listing 3.17, pencarian dilakukan oleh susunan. Saat Anda mengklik tombol dengan id=ok , variabel objek diisi dengan nilai yang dimasukkan dalam bidang teks dengan id=string , dikonversi menjadi tipe int(bilangan bulat). Kemudian nomor tersebut diperiksa untuk melihat apakah nomor tersebut termasuk dalam array. Fungsi $.inArray() digunakan untuk ini. Hasil eksekusi fungsi dapat berupa “-1” - nilai yang dimasukkan tidak ada dalam array, atau nomor seri elemen yang ditemukan (ingat bahwa penomoran dalam array dimulai dari 0). Sekarang cukup memeriksa apakah hasil pencariannya sama dengan “-1”. Jika ya, tampilkan pesan kesalahan. Jika tidak, tampilkan nomor serinya. Dalam kedua kasus tersebut, string dibentuk untuk kejelasan yang lebih baik.

    Tentu saja contoh (Listing 3.17) masih jauh dari sempurna. Pengguna tidak hanya dapat memasukkan angka, tetapi juga string ke dalam kolom teks. Untuk analisis saja nilai numerik Anda dapat melarang masukan simbol atau memeriksa nilai yang dimasukkan untuk melihat apakah nilai tersebut berisi simbol. Opsi pertama telah dibahas dalam bab ini. Menurut kami, lebih tepat jika nilai yang dimasukkan harus selalu bilangan bulat.

    Hasil eksekusi kode JS mirip dengan Gambar. 3.7.


    Beras. 3.7. Cari dalam array

    Mari kita mempersulit tugas ini. Mari kita diberi array nilai kunci. Pengguna dapat masuk bidang teks bentuk kunci dan nilai (Listing 3.18). Penting untuk memeriksa apakah kunci yang dimasukkan ada dalam array. Penting juga untuk memeriksa nilai yang dimasukkan oleh pengguna dengan nilai yang telah ditentukan (Listing 3.19).

    Daftar 3.18. File 1.html - Formulir untuk memasukkan nilai

  • Pemrosesan Array
  • OKE
  • Daftar 3.19. file myscript.js - Mencari array nilai kunci

  • $(dokumen).siap(fungsi() (
  • var array = ("satu":"ini adalah nilai kunci satu", "dua":"ini adalah nilai kunci dua", "tiga":"ini adalah nilai kunci tiga");
  • $("#ok").klik(fungsi() (
  • var kunci = $("#kunci").val();
  • var nilai = $("#nilai").val();
  • var in_array = salah;
  • var kunci = Objek.kunci(array);
  • for (var indeks=0; indeks>> var array = [ 1 , 2 , 3 ]; tidak terdefinisi >>> 3 dalam array ; false >>> array . hasOwnProperty (3 ); false >>> 3 dalam array ; false > >> larik __proto__ = [ 1 , 2 , 3 , 4 ]; [ 1 , 2 , 3 , 4 ] >>> 3 dalam larik ;

      Jika Anda membutuhkannya pencarian cepat kunci untuk objek dengan rantai pewarisan prototipe pendek, gunakan.

      Jika Anda menginginkan hal yang sama, tetapi untuk objek dengan rantai warisan yang luas, gunakan Object.prototype.hasOnwProperty

      Jika Anda memerlukan pencarian cepat, gunakan Array.prototype.indexOf untuk Array .

      Tabel hash tidak memiliki fungsi bawaan untuk mencari nilai. Anda tentu saja dapat membuat sendiri, tetapi ada banyak perpustakaan yang sudah menyediakannya. Misalnya, Underscore menyediakannya (menyebutnya indexOf).

    Mereka biasanya mencari elemen bertipe Number, String atau Object dalam sebuah array. Tentu saja, cara tercepat untuk mencari adalah dengan elemen bertipe Number; membandingkan suatu angka, bahkan yang sangat besar, terjadi dengan sangat cepat, lebih mudah untuk memeriksa satu elemen daripada membandingkan string secara leksigrafis, tetapi dengan objek ceritanya sangat berbeda. . Jika kita mencari objek yang kita tambahkan ke array, yaitu membandingkan referensi, ini secepat membandingkan angka, tetapi jika kita perlu mencari berdasarkan properti objek, maka ini bisa memakan waktu yang sangat, sangat lama. waktu yang lama. Secara khusus kasus-kasus sulit, Saya menyarankan Anda untuk membuat semacam hash objek dan membuat peta array terpisah, di mana Anda dapat dengan mudah mencari semua yang perlu Anda temukan.

    Mari kita lihat 6 cara untuk melakukan ini menggunakan JS asli dengan berbagai kebaruan dan 3 cara untuk menganalisisnya menggunakan kerangka kerja populer: jQuery, garis bawah, dan lodash.

    Bagian satu, sayang, dalam gaya allegro

    Pertama, Anda perlu mempelajari kemampuan bahasa asli dan melihat apa yang dapat Anda lakukan sendiri.

    Pencarian langsung

    Mari kita coba menelusuri elemen-elemen array sampai kita memenuhi apa yang kita butuhkan. Seperti biasa, solusi paling sederhana rata-rata adalah yang tercepat.

    Fungsi berisi(arr, elem) ( untuk (var i = 0; i< arr.length; i++) { if (arr[i] === elem) { return true; } } return false; }

    Bekerja di mana saja. Bandingkan secara ketat menggunakan === . Dapat dengan mudah diganti dengan == , ini dapat berguna ketika elemen array jenis yang berbeda, namun mungkin memperlambat penelusuran. Itu juga dapat dimodifikasi dengan menambahkan kemampuan untuk mulai mencari elemen dari akhir. Sangat baik dalam mencari angka dan garis. Sedikit memperluas, kita dapat menambahkan kemampuan untuk mencari elemen berdasarkan kondisi kita sendiri (ini akan membantu kita mencari berdasarkan properti objek atau, misalnya, elemen pertama yang lebih besar dari 100500):

    Fungsi berisi(arr, pred) ( untuk (var i = 0; i< arr.length; i++) { if (typeof pred == "function" && pred(arr[i], i, arr) || arr[i] === elem) { return true; } } return false; }

    Array.prototipe.indexOf()

    Array.prototype.indexOf(searchElement[, fromIndex = 0]) adalah metode lama yang bagus yang membuat semua orang menderita dengan -1 jika tidak ada elemen.

    Fungsi berisi(arr, elem) ( return arr.indexOf(elem) != -1; )

    Ini didukung di mana saja kecuali IE i === elem) != -1; )

    Mengembalikan elemen atau -1 jika tidak ada yang ditemukan. Pencarian menggunakan callback(elem, index, arr) , yaitu, jika fungsi ini mengembalikan true , maka elemen inilah yang dicari. Tentu saja, Anda dapat mengatur sendiri fungsi ini, sehingga metodenya bersifat universal.

    Array.prototipe.findIndex()

    Array.prototype.findIndex(callback[, thisArg]) - sangat mirip dengan metode sebelumnya, hanya saja fungsinya tidak mengembalikan elemen, melainkan indeks. Untuk bersenang-senang, saya akan membuatnya dengan kemampuan untuk meneruskan fungsi saya:

    Fungsi berisi(arr, pred) ( var f = typeof pred == "fungsi" ? pred: (i => i === pred); return arr.findIndex(f) != -1; )

    Array.prototipe.termasuk()

    Array.prototype.includes(searchElement[, fromIndex]) - dan ini ES7, dengan dukungan yang masih sangat kasar. Terakhir, kita akan memiliki metode khusus untuk mengetahui apakah suatu elemen ada di dalam array! Selamat!

    Arr.includes(elem);

    Hanya itu yang diperlukan untuk menemukan elemennya. Argumen untuk fungsi ini sangat mirip dengan Array.prototype.indexOf() . Tapi itu akan mengembalikan nilai benar jika berhasil dan salah jika sebaliknya. Tentu saja, Anda tidak dapat mencari berdasarkan properti objek; untuk ini ada Array.prototype.find() . Seharusnya menjadi yang tercepat, tapi... Mungkin saja lama kelamaan dia akan menjadi yang tercepat.

    Bagian kedua, dengan perhatian, tapi asing dan bergaya sonata

    Sekarang, akhirnya, kita bisa membicarakan topik yang sama, namun dalam konteks beberapa kerangka kerja! Mereka mengatakan bahwa selalu baik untuk melihat apa yang dilakukan orang lain sebelum Anda mulai melakukannya sendiri. Mungkin ini akan membuka mata kita terhadap sesuatu yang menarik!

    jQuery

    jQuery.inArray(value, array [, fromIndex ]) - omong-omong, cukup metode cepat, menurut tes.

    Ia menggunakan kesetaraan ketat === secara internal dan mengembalikan -1 jika tidak menemukan apa pun, dan jika menemukannya, ia akan mengembalikan indeksnya. Untuk kenyamanan dan keseragaman, mari kita bungkus dalam sebuah fungsi:

    Fungsi berisi(arr, elem) ( return jQuery.inArray(elem, arr) != -1; )

    Sekarang mari kita bicara tentang cara kerjanya. Berikut ini versi 2.1.3:

    InArray: fungsi(elem, arr, i) ( return arr == null ? -1: indexOf.call(arr, elem, i); )

    Di mana indexOf ini:

    // Gunakan indexOf yang disederhanakan karena lebih cepat dari yang asli // ​​http://jsperf.com/thor-indexof-vs-for/5 indexOf = function(list, elem) ( var i = 0, len = daftar.panjang;untuk(;i< len; i++) { if (list[i] === elem) { return i; } } return -1; }

    Sebuah komentar lucu mengatakan bahwa ini lebih cepat daripada Array.prototype.indexOf() asli (saya dapat berasumsi bahwa karena kurangnya semua pemeriksaan) dan menyarankan untuk melihat tes kinerja.

    Sebenarnya ini adalah cara pertama dari bagian pertama.

    Menggarisbawahi

    _.contains(list, value) - ini adalah metode yang ditawarkan kepada kami oleh perpustakaan populer untuk bekerja dengan koleksi. Sama seperti _.include(list, value) .

    Penggunaan === untuk perbandingan. Mengembalikan nilai benar jika daftar berisi elemen yang kita cari. Jika daftar adalah array, metode indexOf akan dipanggil.

    Berisi = _.include = function(obj, target) ( if (obj == null) return false; if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; return any( obj, fungsi(nilai) ( nilai kembalian === target; ));

    Dimana nativeIndexOf adalah sesuatu yang mengatakan bahwa Array.prototype.indexOf() ada, dan obj.indexOf === nativeIndexOf mengatakan bahwa daftar adalah sebuah array. Sekarang Anda dapat melihat mengapa metode ini lebih lambat dari jQuery.inArray(), yang hanya membungkus Array.prototype.indexOf(). Tidak ada yang menarik.

    Lodash

    _.includes(koleksi, target, ) - ini dia harapan terakhir untuk pemikiran baru, dari perpustakaan paling terkenal kedua untuk bekerja dengan koleksi. Sama seperti _.contains() dan _.include() .

    Mengembalikan nilai benar jika berisi dan salah jika tidak. fromIndex indeks elemen untuk memulai pencarian.

    Fungsi termasuk(koleksi, target, fromIndex, penjaga) ( var length = koleksi ? getLength(koleksi) : 0; if (!isLength(length)) ( koleksi = nilai(koleksi); panjang = koleksi.panjang; ) if (typeof fromIndex != "angka" ||. (penjaga && isIterateeCall(target, fromIndex, penjaga))) ( fromIndex = 0; ) lain ( fromIndex = fromIndex< 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); } return (typeof collection == "string" || !isArray(collection) && isString(collection)) ? (fromIndex -1) : (!!length && getIndexOf(collection, target, fromIndex) > -1); }

    penjaga - argumen layanan. Pertama, panjang koleksi ditemukan, fromIndex dipilih, dan kemudian... tidak, bukan Array.prototype.indexOf() ! Untuk mencari string, kita menggunakan String.prototype.indexOf() , dan kita melangkah lebih jauh ke _.getIndexOf() dan sebagai hasilnya kita mendapatkan implementasi LoDash dari indexOf() :

    Fungsi indexOf(array, value, fromIndex) ( var length = array ? array.length: 0; if (!length) ( return -1; ) if (typeof fromIndex == "number") ( fromIndex = fromIndex< 0 ? nativeMax(length + fromIndex, 0) : fromIndex; } else if (fromIndex) { var index = binaryIndex(array, value); if (index < length && (value === value ? (value === array) : (array !== array))) { return index; } return -1; } return baseIndexOf(array, value, fromIndex || 0); }

    Menarik karena fromIndex dapat mengambil nilai Number dan Boolean, dan jika masih berupa nilai Boolean dan bernilai true , maka fungsinya akan menggunakan pencarian biner melalui array! Dingin. Jika tidak, indexOf() akan dieksekusi dengan cara yang lebih sederhana:

    Fungsi baseIndexOf(array, value, fromIndex) ( if (value !== value) ( ​​​​return indexOfNaN(array, fromIndex); ) var indeks = fromIndex - 1, length = array.length; while (++index< length) { if (array === value) { return index; } } return -1; }

    Sebuah langkah yang menarik untuk kasus ketika kita mencari NaN (izinkan saya mengingatkan Anda bahwa, karena kesalahan yang mengganggu, itu tidak sama dengan dirinya sendiri). indexOfNaN() akan dieksekusi, dan memang tidak satu pun dari semua metode yang dijelaskan sebelumnya dapat menemukan NaN , kecuali, tentu saja, di mana kita sendiri dapat menentukan fungsi untuk memilih elemen.

    Seseorang mungkin menyarankan untuk membungkus _.indexOf() saja untuk menemukan elemen:

    Fungsi berisi(arr, elem, fromIndex) ( return _.indexOf(arr, elem, fromIndex) != -1; )

    Dimana fromIndex akan menjadi indeks tempat kita memulai pencarian, atau true jika kita tahu bahwa arr sudah diurutkan.

    Kesimpulannya, meski dalam gaya Intermezzo

    Dan ya, semua opsi ini hanya masuk akal jika momen pencarian data sering terjadi dalam algoritme Anda atau pencarian terjadi pada data yang sangat besar. Berikut beberapa pengujian di bawah ini untuk mencari elemen bertipe Number dan String pada array dengan panjang 1.000.000 (juta) elemen untuk tiga kasus ketika elemen tersebut terletak di awal array, di tengah (dapat dianggap situasi rata-rata untuk array tersebut). palet) dan di akhir (dapat dianggap sebagai elemen yang hilang waktu pencarian kecuali metode dengan Array.prototype.lastIndexOf()).

    • Sergei Savenkov

      semacam ulasan "pendek"... seolah-olah mereka sedang terburu-buru di suatu tempat