วิธีหานาที / สูงสุดด้วย Ruby


415

ฉันต้องการใช้หรือmin(5,10) Math.max(4,7)มีฟังก์ชั่นสำหรับเอฟเฟกต์นี้ใน Ruby หรือไม่?

คำตอบ:


722

คุณทำได้

[5, 10].min

หรือ

[4, 7].max

พวกเขามาจากโมดูล Enumerableดังนั้นสิ่งใดก็ตามที่รวมถึงEnumerableจะมีวิธีการเหล่านั้น

v2.4 แนะนำตัวเองArray#minและArray#maxซึ่งเป็นวิธีที่เร็วกว่าวิธีการ Enumerable #eachเพราะพวกเขาข้ามเรียก

@nicholasklick กล่าวถึงตัวเลือกอื่นแต่เวลานี้กลับอาร์เรย์ของEnumerable#minmax[min, max]

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

3
@kaz ฉันไม่แน่ใจว่าฉันเข้าใจความคิดเห็นของคุณ
Ziggy

3
@Kaz ... คุณรู้ว่าstd::max(4, 7)มี "เครื่องหมายวรรคตอน" มากกว่า[4, 7].max?
tckmn

3
@Doorknob คุณตระหนักดีว่าstd::maxสามารถนำเข้าสู่เนมสเปซของคุณmax(4, 7)ได้ รอ; เมื่อมองไปด้านบนฉันเห็นว่าฉันพูดไปแล้ว
Kaz

18
เครื่องหมายวรรคตอนไม่ใช่ปัญหาที่นี่ การจัดสรรฮีปทั้งหมดเพื่อให้ได้ค่ามากที่สุดคือความอัปลักษณ์พื้นฐานที่นี่
kdbanman

7
Ruby ส่วนใหญ่สำหรับโปรแกรมเมอร์ไม่ใช่สำหรับคอมพิวเตอร์ ในคำพูดของ Matz "ฉันหวังว่าจะเห็น Ruby ช่วยโปรแกรมเมอร์ทุกคนในโลกให้มีประสิทธิผลและสนุกกับการเขียนโปรแกรมและมีความสุขนั่นคือจุดประสงค์หลักของภาษารูบี" มาจากหน้า Wikipedia บน Ruby
aaron-coding

52

คุณสามารถใช้ได้

[5,10].min 

หรือ

[4,7].max

มันเป็นวิธีการสำหรับอาร์เรย์


20
ในทางเทคนิคมันเป็นวิธีการสำหรับ Enumerables ไม่ใช่อาร์เรย์
meagar

1
มันเป็นวิธีการสำหรับอาร์เรย์ที่มีประสิทธิภาพที่เหนือกว่าของ Enumerable ตั้งแต่ v2.4
Andre Figueiredo

25

ผลลัพธ์ทั้งหมดเหล่านั้นสร้างขยะในความพยายามอย่างกระตือรือร้นเพื่อจัดการมากกว่าสองข้อโต้แย้ง ฉันอยากรู้ว่าพวกเขาปฏิบัติอย่างไรเมื่อเปรียบเทียบกับ ol ดี:

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

ซึ่งก็คือคำตอบอย่างเป็นทางการของฉันสำหรับคำถามของคุณ


มีบางคำพูดที่ Ruby 2.4 กำลังปรับให้เหมาะสม[a,b].maxแต่ก็ยังไม่ชัดเจนว่าจะเร็วกว่าการใช้งานด้านบนหรือไม่ blog.bigbinary.com 2016/11/17/…
Dave Morse

2
นี่คือการเพิ่มประสิทธิภาพแบบไมโครทั้งสองอย่างรวดเร็วแตกต่างกันเล็กน้อยดูมาตรฐาน: repl.it/@AndreFigueiredo/earearirdirdSweepsoftware
Andre Figueiredo

1
การทำโปรไฟล์นี้คำนึงถึงเวลาที่ใช้ใน GC หรือไม่
Dave Morse

20

หากคุณต้องการค้นหาแฮ็กสูงสุด / นาทีคุณสามารถใช้#max_byหรือ#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

นอกเหนือจากคำตอบที่ให้แล้วหากคุณต้องการแปลงEnumerable # maxเป็นวิธีการสูงสุดที่สามารถเรียกหมายเลขตัวแปรหรืออาร์กิวเมนต์เช่นในภาษาการเขียนโปรแกรมอื่นคุณสามารถเขียน:

def max(*values)
 values.max
end

เอาท์พุท:

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

สิ่งนี้ใช้ในทางที่ผิดของผู้ประกอบการ splat เพื่อสร้างวัตถุอาร์เรย์ที่มีข้อโต้แย้งทั้งหมดที่มีให้หรือวัตถุอาร์เรย์ที่ว่างเปล่าถ้าไม่มีข้อโต้แย้งที่ได้รับ ในกรณีหลังนี้วิธีการที่จะกลับมาnilตั้งแต่เรียกEnumerable # สูงสุดnilบนอาร์เรย์ว่างผลตอบแทนวัตถุ

หากคุณต้องการกำหนดวิธีการนี้ในโมดูลคณิตศาสตร์สิ่งนี้ควรทำเคล็ดลับ:

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

โปรดทราบว่า Enumerable.max เป็นอย่างน้อยสองครั้งช้าเมื่อเทียบกับผู้ประกอบการที่ประกอบไปด้วย (?: ) ดูคำตอบของ Dave Morseสำหรับวิธีที่ง่ายและรวดเร็วยิ่งขึ้น


แต่ไม่ได้เปิดคลาสมาตรฐานและโมดูลอีกครั้งถือว่าเป็นการปฏิบัติที่ไม่ดีใช่หรือไม่
radiantshaw

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

การเรียงลำดับเพื่อค้นหาค่าสูงสุด / ต่ำสุดนั้นสิ้นเปลือง การค้นหา min / max คือ O (n) ในขณะที่ sorting คือ O (n log (n))
Itamar Mushkin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.