Cách tìm min / max với Ruby


415

Tôi muốn sử dụng min(5,10), hoặc Math.max(4,7). Có chức năng nào cho hiệu ứng này trong Ruby không?

Câu trả lời:


723

Bạn có thể làm

[5, 10].min

hoặc là

[4, 7].max

Chúng đến từ mô-đun En đếm , vì vậy bất cứ điều gì bao gồm Enumerablesẽ có sẵn các phương thức đó.

v2.4 giới thiệu riêng Array#minArray#max, nhanh hơn các phương thức của Enumerable vì họ bỏ qua cuộc gọi #each.

@nicholasklick đề cập đến một tùy chọn khác Enumerable#minmax, nhưng lần này trả về một mảng [min, max].

[4, 5, 7, 10].minmax
=> [4, 10]

3
@kaz Tôi không chắc là tôi hiểu bình luận của bạn.
Ziggy

3
@Kaz ... bạn nhận ra std::max(4, 7)có nhiều "dấu câu" hơn [4, 7].max?
tckmn

3
@Doorknob Bạn có nhận ra rằng std::maxcó thể được nhập vào không gian tên của bạn để nó trở thành max(4, 7). Chờ đợi; Nhìn phía trên, tôi thấy tôi đã nói điều đó rồi.
Kaz

18
Dấu câu không phải là vấn đề ở đây. Toàn bộ phân bổ heap để có được tối đa một vài giá trị là sự xấu xí tiềm ẩn ở đây.
kdbanman

7
Ruby chủ yếu dành cho lập trình viên chứ không phải cho máy tính. Theo lời của Matz "Tôi hy vọng sẽ thấy Ruby giúp mọi lập trình viên trên thế giới làm việc hiệu quả, và thích lập trình, và hạnh phúc. Đó là mục đích chính của ngôn ngữ Ruby." Đó là từ trang Wikipedia trên Ruby.
mã hóa aaron

52

Bạn có thể dùng

[5,10].min 

hoặc là

[4,7].max

Đó là một phương pháp cho Mảng.


20
Về mặt kỹ thuật, đây là một phương pháp cho Vô số, không phải Mảng.
meagar

1
Đó là một phương pháp cho Mảng với hiệu suất vượt trội so với Enumerable kể từ phiên bản 2.4
Andre Figueiredo

25

Tất cả những kết quả đó tạo ra rác trong một nỗ lực nhiệt tình để xử lý nhiều hơn hai đối số. Tôi tò mò muốn xem cách họ thể hiện so với 'ol tốt:

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

Nhân tiện, đây là câu trả lời chính thức cho câu hỏi của bạn.


Có một số tin đồn rằng Ruby 2.4 đang tối ưu hóa [a,b].max, nhưng vẫn chưa rõ liệu nó có nhanh hơn so với triển khai ở trên không. blog.bigbinary.com/2016/11/17/õ
Dave Morse

2
Đây là tối ưu hóa vi mô, cả hai đều rất nhanh, sự khác biệt là không đáng kể, xem điểm chuẩn: repl.it/@AndreFigueiredo/DearweirdSweepsoftware
Andre Figueiredo

1
Liệu hồ sơ này có tính đến thời gian trong GC?
Dave Morse

20

Nếu bạn cần tìm tối đa / phút của hàm băm, bạn có thể sử dụng #max_byhoặc#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]

20

Ngoài các câu trả lời được cung cấp, nếu bạn muốn chuyển đổi Enumerable # max thành một phương thức tối đa có thể gọi một số biến hoặc đối số, như trong một số ngôn ngữ lập trình khác, bạn có thể viết:

def max(*values)
 values.max
end

Đầu ra:

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

Điều này lạm dụng các thuộc tính của toán tử splat để tạo một đối tượng mảng chứa tất cả các đối số được cung cấp hoặc một đối tượng mảng trống nếu không có đối số nào được cung cấp. Trong trường hợp sau, phương thức sẽ trả về nil, vì gọi Enumerable # max trên một đối tượng mảng trống trả về nil.

Nếu bạn muốn xác định phương thức này trên mô-đun Math, thì nên thực hiện thủ thuật này:

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

Lưu ý rằng Enumerable.max chậm hơn hai lần so với toán tử ternary ( ?:) . Xem câu trả lời của Dave Morse cho một phương pháp đơn giản và nhanh hơn.


Nhưng không mở lại các lớp và mô-đun tiêu chuẩn được coi là một thực tiễn xấu?
radiantshaw

-2
def find_largest_num(nums)
  nums.sort[-1]
end

phân loại để tìm tối đa / tối thiểu là lãng phí; tìm min / max là O (n), trong khi sắp xếp là O (n log (n)).
Nấm Itamar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.