Bagaimana saya bisa dengan mudah mendapatkan elemen min atau max dari JavaScript Array?
Contoh Psuedocode:
let array = [100, 0, 50]
array.min() //=> 0
array.max() //=> 100
javascript
Terima kasih
sumber
sumber
...
) denganMath.max()
seperti ini:Math.max(...[2, 5, 16, 1])
. Lihat jawaban saya yang dibuat dari dokumentasi MDN .Math.max.apply(null, [2,5,16,1])
Jawaban:
Bagaimana dengan menambah objek Array bawaan untuk menggunakan
Math.max
/Math.min
sebagai gantinya:Ini JSFiddle .
Menambah built-in dapat menyebabkan tabrakan dengan perpustakaan lain (beberapa lihat), sehingga Anda mungkin lebih nyaman dengan hanya
apply
'ingMath.xxx()
ke array Anda secara langsung:Sebagai alternatif, dengan asumsi browser Anda mendukung ECMAScript 6, Anda dapat menggunakan operator spread yang fungsinya mirip dengan
apply
metode ini:sumber
null
atauMath
atau{}
atau apa punapply()
ataucall()
tidak ada hubungannya dengan hasilnya.Math.max
tidak atau tidak seharusnya merujuk secarathis
internal.Math.max.apply(null, $.makeArray(array));
.max
atau.min
metode di masa depan. Skenario realistis yang sempurna: Anda menggunakan jawaban ini. Pada 2016, spesifikasi ES7 atau ES8Array.max
danArray.min
. Tidak seperti versi ini, mereka bekerja pada string. Kolega Anda di masa depan mencoba untuk mendapatkan string alfabetis terbaru dalam array dengan.max()
metode asli yang terdokumentasi dengan baik , tetapi secara misterius dapatNaN
. Beberapa jam kemudian, dia menemukan kode ini, menjalankangit blame
, dan mengutuk namamu.Untuk diskusi lengkap, lihat: http://aaroncrane.co.uk/2008/11/javascript_max_api/
sumber
Math.max.apply(Math, array)
danMath.max.apply(null, array)
? Blog mengatakan "... Anda juga harus secara berlebihan mengatakan lagi bahwa itumax
milikMath
...", tetapi sepertinya saya tidak harus melakukannya (dengan menetapkan argumen pertamaapply
sebagainull
).Math.max(a,b)
,Math
dilewatkan sebagaithis
nilai, jadi mungkin masuk akal untuk melakukan hal yang sama saat menelepon denganapply
. TetapiMath.max
tidak menggunakanthis
nilai tersebut, sehingga Anda bisa melewati nilai apa pun yang Anda inginkan.Untuk array besar (~ 10⁷ elemen),
Math.min
danMath.max
keduanya menghasilkan kesalahan berikut di Node.js.Solusi yang lebih kuat adalah dengan tidak menambahkan setiap elemen ke tumpukan panggilan, tetapi untuk meneruskan array:
Jika Anda khawatir tentang kecepatan, kode berikut ~ 3 kali lebih cepat
Math.max.apply
dari pada komputer saya. Lihat http://jsperf.com/min-and-max-in-array/2 .Jika array Anda mengandung string, bukan angka, Anda juga perlu memaksa mereka menjadi angka. Kode di bawah ini melakukan itu, tetapi memperlambat kode ~ 10 kali pada mesin saya. Lihat http://jsperf.com/min-and-max-in-array/3 .
sumber
min
danmax
untuk elemen terakhir dan mengurangi iterasi oleh 1 (while(--len)
);)very different results
Anda melakukannya 5 tahun kemudian)reduce
solusi adalah yang paling lambat. Bahkan jika Anda bekerja dengan array yang memiliki jutaan elemen, lebih baik menggunakan standar untuk loop . Lihat jawaban saya untuk lebih lanjut.Menggunakan spread operator (ES6)
Tampilkan cuplikan kode
sumber
If no arguments are given, the result is -∞.
tl; dr
Solusi MDN
Dokumen MDN resmi pada
Math.max()
sudah mencakup masalah ini:Ukuran maksimum array
Menurut MDN yang
apply
dan penyebaran solusi memiliki keterbatasan dari 65.536 yang berasal dari batas jumlah maksimum argumen:Mereka bahkan menyediakan solusi hybrid yang tidak benar-benar memiliki kinerja yang baik dibandingkan dengan solusi lain. Lihat tes kinerja di bawah ini untuk informasi lebih lanjut.
Pada 2019 batas sebenarnya adalah ukuran maksimum tumpukan panggilan . Untuk browser desktop berbasis Chromium modern ini berarti bahwa ketika datang untuk mencari min / max dengan
apply
atau menyebar, praktis ukuran maksimum untuk angka array hanya ~ 120000 . Di atas ini, akan ada stack overflow dan kesalahan berikut akan dilemparkan:Dengan skrip di bawah ini (berdasarkan posting blog ini ), dengan menangkap kesalahan itu Anda dapat menghitung batas untuk lingkungan spesifik Anda.
Peringatan! Menjalankan skrip ini membutuhkan waktu dan tergantung pada kinerja sistem Anda, mungkin memperlambat atau merusak browser / sistem Anda!
Performa pada array besar
Berdasarkan pengujian pada komentar EscapeNetscape saya membuat beberapa tolok ukur yang menguji 5 metode berbeda pada array angka acak saja dengan 100000 item .
Pada 2019, hasilnya menunjukkan bahwa loop standar (yang BTW tidak memiliki batasan ukuran) adalah yang tercepat di mana-mana.
apply
dan penyebaran datang setelah itu, kemudian solusi hybrid MDN kemudianreduce
sebagai yang paling lambat.Hampir semua tes memberikan hasil yang sama, kecuali untuk tes yang penyebarannya paling lambat.
Jika Anda meningkatkan array Anda untuk memiliki 1 juta item, hal-hal mulai rusak dan Anda dibiarkan dengan loop standar sebagai solusi cepat dan
reduce
lebih lambat.Tolok ukur JSPerf
Tolok ukur JSBen
Tolok ukur JSBench.me
Kode sumber patokan
Tampilkan cuplikan kode
sumber
Math.max.apply(Math, arr)
untuk kompatibilitas 'maks'.(...)
danapply
akan gagal atau mengembalikan hasil yang salah jika array memiliki terlalu banyak elemen [...] Solusi pengurangan tidak memiliki masalah ini" Pengujian Chrome, FF, Edge dan IE11 tampaknya seperti itu adalah ok untuk array hingga nilai 100k. (Diuji pada Win10 dan browser terbaru: Chrome 110k, Firefox 300k, Edge 400k, IE11 150k).Jika Anda paranoid seperti saya tentang penggunaan
Math.max.apply
(yang dapat menyebabkan kesalahan saat diberi array besar sesuai dengan MDN ), coba ini:Atau, dalam ES6:
Sayangnya, fungsi anonim diperlukan (alih-alih menggunakan
Math.max.bind(Math)
karenareduce
tidak hanya meneruskana
danb
ke fungsinya, tetapi jugai
dan referensi ke array itu sendiri, jadi kami harus memastikan kami tidak mencoba memanggilnyamax
juga.sumber
Math.max(...array)
?apply
, dan oleh karena itu memiliki kelemahan yang sama (batas argumen maksimum).function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
Math.min()
tanpa nilai, kembaliInfinity
, jadi fungsi ini bisa digunakanreduce(..., Infinity)
untuk mencocokkan perilaku itu. Saya lebih suka untuk melempar pengecualian (seperti halnya saat ini), karena mengambil minimum array kosong sepertinya merupakan kesalahan..apply
sering digunakan ketika tujuannya adalah untuk memanggil fungsi variad dengan daftar nilai argumen, misalnyaThe
Math.max([value1[,value2, ...]])
fungsi mengembalikan terbesar dari nol atau lebih nomor.The
Math.max()
Metode tidak memungkinkan Anda untuk lulus dalam array. Jika Anda memiliki daftar nilai yang Anda butuhkan untuk mendapatkan yang terbesar, Anda biasanya akan memanggil fungsi ini menggunakan Function.prototype.apply () , misalnyaNamun, pada ECMAScript 6 Anda dapat menggunakan operator spread :
Menggunakan operator spread, yang di atas dapat ditulis ulang seperti:
Saat memanggil fungsi menggunakan operator variadic, Anda bahkan dapat menambahkan nilai tambahan, mis
Bonus:
Operator spread memungkinkan Anda untuk menggunakan array literal sintaks untuk membuat array baru dalam situasi di mana di ES5 Anda akan perlu untuk jatuh kembali ke kode penting, menggunakan kombinasi
push
,splice
dllsumber
concat
sebagian besar programmer karena memungkinkan Anda mempertahankan gaya baris tunggal.Dua cara lebih pendek dan mudah:
Cara 1 :
Cara 2 :
sumber
0
menggunakannya, Anda dapat menggunakan[0].concat(arr)
atau dengan sintaks spread[0, ...arr]
(sebagai ganti 'arr')Anda melakukannya dengan memperluas tipe Array:
Didorong dari sini (oleh John Resig)
sumber
Solusi sederhana untuk menemukan nilai minimum atas
Array
elemen adalah dengan menggunakanArray
fungsi prototipereduce
:atau menggunakan fungsi Math.Min () bawaan JavaScript (terima kasih @Tenflex):
Ini diatur
min
keA[0]
, dan kemudian memeriksaA[1]...A[n]
apakah itu benar-benar kurang dari saat inimin
. JikaA[i] < min
kemudianmin
diperbarui keA[i]
. Ketika semua elemen array telah diproses,min
dikembalikan sebagai hasilnya.EDIT : Sertakan posisi nilai minimum:
sumber
min
nilai tidak hanya dikembalikan tetapi juga posisinya di Array?Yang lain telah memberikan beberapa solusi yang mereka tambahkan
Array.prototype
. Yang saya inginkan dalam jawaban ini adalah untuk menjelaskan apakah seharusnyaMath.min.apply( Math, array )
atau tidakMath.min.apply( null, array )
. Jadi konteks apa yang harus digunakan,Math
ataunull
?Ketika lewat
null
sebagai konteksapply
, maka konteksnya akan default ke objek global (window
objek dalam hal browser). MelewatiMath
objek sebagai konteks akan menjadi solusi yang tepat, tetapi tidak ada salahnya lewatnull
juga. Berikut ini contoh saatnull
dapat menyebabkan masalah, saat mendekorasiMath.max
fungsi:Di atas akan membuang pengecualian karena
this.foo
akan dievaluasi sebagaiwindow.foo
, yaituundefined
. Jika kita gantinull
denganMath
, semuanya akan berfungsi seperti yang diharapkan dan string "foo" akan dicetak ke layar (saya menguji ini menggunakan Mozilla Rhino ).Anda dapat dengan mudah berasumsi bahwa tidak ada seorang pun yang didekorasi
Math.max
demikian, passingnull
akan bekerja tanpa masalah.sumber
Foo.staticMethod
dan referensithis
? Apakah itu tidak akan menjadi kesalahan dalam desain dekorator? (kecuali tentu saja mereka ingin referensi lingkup global, dan ingin tetap independen dari mesin JavaScript yang digunakan, misalnya Badak).Math.max
, diterapkan per spec, tidak digunakanthis
. Jika seseorang menimpaMath.max
sedemikian rupa sehingga tidak digunakanthis
, maka mereka telah membuat perilakunya melanggar spec dan Anda harus melemparkan benda tajam pada mereka. Anda tidak boleh kode di sekitar kemungkinan itu lebih dari yang Anda kode di sekitar kemungkinan bahwa seseorang telah bertukarMath.max
danMath.min
untuk lulz.Satu lagi cara untuk melakukannya:
Pemakaian:
sumber
Metode Alternatif
Metode
Math.min
danMath.max
keduanya adalah operasi rekursif yang ditambahkan ke tumpukan panggilan mesin JS, dan kemungkinan besar crash untuk array yang berisi sejumlah besar item(lebih dari ~ 10⁷ item, tergantung pada browser pengguna).
Sebagai gantinya, gunakan sesuatu seperti:
Atau dengan run-time yang lebih baik:
Atau untuk mendapatkan Min dan Max:
Atau dengan run-time * yang lebih baik:
* Diuji dengan 1.000.000 item:
Hanya untuk referensi, fungsi run-time 1 (pada mesin saya) adalah 15,84 ms vs fungsi 2 dengan hanya 4,32 ms.
sumber
Ini mungkin sesuai dengan tujuan Anda.
sumber
comparer
seharusnya dipanggil dalam lingkup tertentu? Karena sebagaimana adanya referensithis[index]
yangundefined
setiap saat.Math.xxx
) akan berjalan dalam lingkup global ...https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/max
ini bekerja untuk saya.
sumber
Saya kaget tidak salah menyebut dan mengurangi fungsinya.
sumber
Untuk array besar (~ 10⁷ elemen),
Math.min
danMath.max
menghasilkan RangeError (ukuran stack panggilan maksimum terlampaui) di node.js.Untuk array besar, solusi cepat & kotor adalah:
sumber
Saya memiliki masalah yang sama, saya perlu mendapatkan nilai minimum dan maksimum dari sebuah array dan, yang mengejutkan saya, tidak ada fungsi built-in untuk array. Setelah banyak membaca, saya memutuskan untuk menguji sendiri solusi "3 teratas":
Kode tes adalah ini:
Array A diisi dengan 100.000 angka integer acak, setiap fungsi dijalankan 10.000 kali pada Mozilla Firefox 28.0 pada desktop intel Pentium 4 2.99GHz dengan Windows Vista. Waktu dalam detik, diambil oleh fungsi performance.now (). Hasilnya adalah ini, dengan 3 digit fraksional dan deviasi standar:
Solusi REDUCE lebih lambat 117% dari solusi diskrit. Solusi BERLAKU lebih buruk, 2.118% lebih lambat dari solusi diskrit. Selain itu, seperti yang diamati Peter, itu tidak berfungsi untuk array besar (sekitar lebih dari 1.000.000 elemen).
Juga, untuk menyelesaikan tes, saya menguji kode terpisah yang diperluas ini:
Waktunya: mean = 0,218s, sd = 0,094
Jadi, 35% lebih lambat dari solusi diskrit sederhana, tetapi ia mengambil nilai maksimum dan minimum sekaligus (solusi lain akan membutuhkan setidaknya dua kali lipat untuk mengambilnya). Setelah OP membutuhkan kedua nilai tersebut, solusi diskrit akan menjadi pilihan terbaik (meskipun dua fungsi terpisah, satu untuk menghitung maksimum dan satu lagi untuk menghitung minimum, mereka akan mengungguli yang terbaik kedua, solusi REDUCE).
sumber
Anda dapat menggunakan fungsi berikut di mana saja di proyek Anda:
Dan kemudian Anda bisa memanggil fungsi yang melewati array:
sumber
Kode berikut ini berfungsi untuk saya:
sumber
Iterasi melalui, melacak saat Anda pergi.
Ini akan meninggalkan min / max null jika tidak ada elemen dalam array. Akan menetapkan min dan maks dalam satu lintasan jika array memiliki elemen apa pun.
Anda juga dapat memperluas Array dengan
range
metode menggunakan di atas untuk memungkinkan penggunaan kembali dan meningkatkan keterbacaan. Lihat biola yang berfungsi di http://jsfiddle.net/9C9fU/Digunakan sebagai
sumber
range
fungsi yang akan menjadi cara terbaik untuk mendapatkan min dan max pada saat yang sama IMO - seperti yang telah saya lakukan dengan pembaruan untuk jawaban saya.Saya pikir saya akan membagikan solusi saya yang sederhana dan mudah dipahami.
Untuk min:
Dan untuk maks:
sumber
for…in
enumerasi pada array!Hal-hal sederhana, sungguh.
sumber
Inilah salah satu cara untuk mendapatkan nilai maksimal dari berbagai objek. Buat salinan (dengan irisan), lalu urutkan salinan dalam urutan menurun dan ambil item pertama.
sumber
Menggunakan
Math.max()
atauMath.min()
Fungsi berikut digunakan
Function.prototype.apply()
untuk menemukan elemen maksimum dalam array numerik.getMaxOfArray([1, 2, 3])
setara denganMath.max(1, 2, 3)
, tetapi Anda dapat menggunakangetMaxOfArray()
pada array yang dibangun secara terprogram dari berbagai ukuran.Atau dengan operator spread baru, mendapatkan array maksimum menjadi jauh lebih mudah.
sumber
Selain menggunakan fungsi matematika maks dan min, fungsi lain yang digunakan adalah fungsi bawaan sortir (): ayo kita mulai
sumber
Solusi ChaosPandion berfungsi jika Anda menggunakan protoype. Jika tidak, pertimbangkan ini:
Di atas akan mengembalikan NaN jika nilai array bukan bilangan bulat sehingga Anda harus membangun beberapa fungsi untuk menghindarinya. Kalau tidak, ini akan berhasil.
sumber
Math
objek sebagai konteksnya?Jika Anda menggunakan library sugar.js , Anda dapat menulis arr.min () dan arr.max () seperti yang Anda sarankan. Anda juga bisa mendapatkan nilai min dan maks dari array non-numerik.
Contoh:
Perpustakaan seperti Lo-Dash dan underscore.js juga menyediakan fungsi min dan maks yang kuat serupa:
Contoh dari Lo-Dash:
sumber
sumber
Mencoba
Tampilkan cuplikan kode
Untuk Math.min / maks (+ terapkan) kami mendapatkan kesalahan:
Tampilkan cuplikan kode
sumber