Cara menemukan min / maks dengan Ruby

415

Saya ingin menggunakan min(5,10), atau Math.max(4,7). Apakah ada fungsi untuk efek ini di Ruby?

obuzek
sumber

Jawaban:

723

Anda dapat melakukan

[5, 10].min

atau

[4, 7].max

Mereka datang dari modul Enumerable , jadi apa pun yang termasuk Enumerableakan memiliki metode tersebut tersedia.

v2.4 memperkenalkan sendiri Array#mindan Array#max, yang jauh lebih cepat daripada metode Enumerable karena mereka melewatkan panggilan #each.

@nicholasklick menyebutkan opsi lain Enumerable#minmax, tetapi kali ini mengembalikan array [min, max].

[4, 5, 7, 10].minmax
=> [4, 10]
theIV
sumber
3
@ kaz Saya tidak yakin saya mengerti komentar Anda.
Ziggy
3
@ Ka ... kamu sadar std::max(4, 7)memiliki lebih banyak "tanda baca" daripada [4, 7].max?
tckmn
3
@ DooNorknob Anda benar-benar menyadari bahwa std::maxdapat diimpor ke namespace Anda sehingga menjadi max(4, 7). Tunggu; melihat di atas, saya melihat saya sudah mengatakan itu.
Kaz
18
Tanda baca bukan masalah di sini. Seluruh alokasi heap untuk mendapatkan maks beberapa nilai adalah keburukan yang mendasarinya di sini.
kdbanman
7
Ruby utamanya untuk programmer bukan untuk komputer. Dalam kata-kata Matz, "Saya berharap melihat Ruby membantu setiap programmer di dunia untuk menjadi produktif, dan untuk menikmati pemrograman, dan menjadi bahagia. Itulah tujuan utama bahasa Ruby." Itu dari halaman Wikipedia di Ruby.
Aaron-coding
52

Kamu bisa menggunakan

[5,10].min 

atau

[4,7].max

Ini adalah metode untuk Array.

Diego Dias
sumber
20
Secara teknis ini adalah metode untuk Enumerables, bukan Array.
meagar
1
Ini adalah metode untuk Array dengan kinerja lebih unggul dari Enumerable sejak v2.4
Andre Figueiredo
25

Semua hasil tersebut menghasilkan sampah dalam upaya yang bersemangat untuk menangani lebih dari dua argumen. Saya ingin tahu bagaimana kinerjanya dibandingkan dengan yang baik:

def max (a,b)
  a>b ? a : b
end

yaitu, by-the-way, jawaban resmi saya untuk pertanyaan Anda.

Dave Morse
sumber
Ada beberapa gemuruh yang dioptimalkan oleh Ruby 2.4 [a,b].max, tetapi masih belum jelas apakah ini lebih cepat dari implementasi di atas. blog.bigbinary.com/2016/11/17/…
Dave Morse
2
ini adalah mikro-optimasi, mereka berdua sangat cepat, perbedaannya dapat diabaikan, lihat benchmark: repl.it/@AndreFigueiredo/DearWeirdSweepsoftware
Andre Figueiredo
1
Apakah profil ini memperhitungkan waktu yang dihabiskan di GC?
Dave Morse
20

Jika Anda perlu mencari maks / min hash, Anda bisa menggunakan #max_byatau#min_by

people = {'joe' => 21, 'bill' => 35, 'sally' => 24}

people.min_by { |name, age| age } #=> ["joe", 21]
people.max_by { |name, age| age } #=> ["bill", 35]
aaron-coding
sumber
20

Selain jawaban yang diberikan, jika Anda ingin mengonversi Enumerable # max menjadi metode max yang dapat memanggil nomor variabel atau argumen, seperti dalam beberapa bahasa pemrograman lain, Anda dapat menulis:

def max(*values)
 values.max
end

Keluaran:

max(7, 1234, 9, -78, 156)
=> 1234

Ini menyalahgunakan properti operator percikan untuk membuat objek array yang berisi semua argumen yang disediakan, atau objek array kosong jika tidak ada argumen yang disediakan. Dalam kasus terakhir, metode ini akan kembali nil, karena memanggil Enumerable # max pada objek array kosong akan kembali nil.

Jika Anda ingin mendefinisikan metode ini pada modul Matematika, ini harus melakukan trik:

module Math
 def self.max(*values)
  values.max
 end
end

Perhatikan bahwa Enumerable.max, setidaknya, dua kali lebih lambat dibandingkan dengan operator ternary ( ?:) . Lihat jawaban Dave Morse untuk metode yang lebih sederhana dan lebih cepat.

HamsterMuffin
sumber
Tetapi bukankah membuka kembali kelas dan modul standar dianggap praktik yang buruk?
radiantshaw
-2
def find_largest_num(nums)
  nums.sort[-1]
end
Almokhtar bekkour
sumber
penyortiran untuk menemukan maksimum / minimum boros; menemukan min / maks adalah O (n), sedangkan pengurutan adalah O (n log (n)).
Itamar Mushkin