Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

วิธีจัดเรียงอาร์เรย์ &แฮชใน Ruby (รวมตัวอย่าง)

การจัดเรียงอาร์เรย์ใน Ruby เป็นเรื่องง่าย!

คุณ ไม่จำเป็นต้องเขียนอัลกอริธึมแฟนซี เพื่อให้ได้ผลลัพธ์ที่คุณต้องการ

แล้วต้องใช้อะไรบ้าง?

ทำความเข้าใจวิธีการจัดเรียงในตัวของ Ruby

สิ่งเหล่านี้ :

  • จัดเรียง
  • sort_by
  • เรียงลำดับ!

วิธีการเหล่านี้ทำงานอย่างไรและทำไมจึงแตกต่างกัน

นั่นคือสิ่งที่คุณจะได้ค้นพบในบทความนี้

คุณจะได้เรียนรู้วิธีจัดเรียงอาร์เรย์ต่างๆ โดยเริ่มจาก sort วิธีการแล้วดูที่ sort_by สำหรับการจัดเรียงขั้นสูง (ตามค่าหลายค่า) และอื่นๆ

มาทำสิ่งนี้กันเถอะ!

เรียนรู้การใช้ Sort &Sort! วิธีการทับทิม

รูปแบบพื้นฐานที่สุดของการเรียงลำดับมีให้โดยวิธีการเรียงลำดับ Ruby ซึ่งกำหนดโดยโมดูล Enumerable

มาดูตัวอย่างกัน :

numbers = [5,3,2,1]

numbers.sort
# [1,2,3,5]

สังเกตว่า sort จะส่งคืนอาร์เรย์ใหม่พร้อมผลลัพธ์

อาร์เรย์ขององค์ประกอบที่จัดเรียง!

นอกจากนี้ยังสามารถจัดเรียง "แทนที่" โดยใช้ sort! วิธีการ

ซึ่งหมายความว่าอาร์เรย์เดิมจะ เปลี่ยน แทนที่จะสร้างใหม่ ซึ่งอาจเป็นผลดีต่อประสิทธิภาพ

การเรียงลำดับแบบกำหนดเองด้วย sort_by

ด้วย sort_by วิธีที่คุณสามารถทำการเรียงลำดับขั้นสูงและน่าสนใจยิ่งขึ้น

คุณจะสามารถ :

  • จัดเรียงตามความยาวของสตริง
  • จัดเรียงตามเนื้อหาสตริง
  • จัดเรียงตามว่าตัวเลขเป็นคู่หรือคี่

คุณสามารถทำได้โดยใช้ sort_by เมธอด &บล็อกทับทิม

ตัวอย่างเช่น :

strings = %w(foo test blog a)

strings.sort_by(&:length)

# ["a", "foo", "test", "blog"]

วิธีนี้ทำงานอย่างไร

ก็ sort_by method ต้องการค่าตัวเลข นั่นคือสาเหตุที่ length ได้ผล

หากคุณเข้าใจสิ่งนี้ คุณสามารถใช้วิธีนี้ทำสิ่งดีๆ ได้ เช่น การจัดเรียงคำที่ขึ้นต้นด้วยตัวพิมพ์ใหญ่และปล่อยให้ทุกอย่างเข้าที่

ถูกใจสิ่งนี้ :

def sort_by_capital_word(text)
  text
    .split
    .sort_by { |w| w[0].match?(/[A-Z]/) ? 0 : 1 }
    .join(" ")
end

sort_by_capital_word("calendar Cat tap Lamp")

# "Cat Lamp calendar tap"

นอกจากนี้ยังสามารถทำการเรียงลำดับแบบกำหนดเองโดยใช้ sort . ปกติ วิธีที่มีบล็อก

นี่คือตัวอย่าง :

strings = %w(foo test blog a)

strings.sort { |a,b| a.length <=> b.length }

# ["a", "foo", "test", "blog"]

หมายเหตุ :นี่ <=> สัญลักษณ์นี้เรียกว่า "ผู้ดำเนินการยานอวกาศ" และเป็นวิธีการที่คุณสามารถนำไปใช้ในชั้นเรียนของคุณได้ ควรคืนค่า 1 (มากกว่า), 0 (เท่ากับ) หรือ -1 (น้อยกว่า)

โดยทั่วไป ฉันชอบ sort_by เพราะเจตนาชัดเจนขึ้น อ่านง่ายกว่า และเร็วกว่านิดหน่อย

เรียงลำดับย้อนกลับ

แล้วการเรียงลำดับย้อนกลับล่ะ

คุณสามารถใช้ reverse วิธีหลังจากการเรียงลำดับ หรือคุณสามารถใช้บล็อก &ใส่เครื่องหมายลบหน้าสิ่งที่คุณกำลังเรียงลำดับ

ให้ฉันแสดงตัวอย่างให้คุณดู :

strings = %w(foo test blog a)

strings.sort_by { |str| -str.length }

# ["blog", "test", "foo", "a"]

ไม่หรูหรา แต่ใช้งานได้! 🙂

การเรียงลำดับตัวอักษรและตัวเลข

สมมติว่าคุณต้องการจัดเรียงรายการสตริงที่มีตัวเลขเป็นตัวเลข

ถูกใจสิ่งนี้ :

music = %w(21.mp3 10.mp3 5.mp3 40.mp3)

โดยค่าเริ่มต้น คุณจะไม่ได้รับการจัดเรียงรายการนี้ตามที่คุณต้องการ

ตัวอย่าง :

music.sort

# ["10.mp3", "21.mp3", "40.mp3", "5.mp3"]

แต่คุณสามารถแก้ไขได้โดยใช้ sort_by :

music.sort_by { |s| s.scan(/\d+/).first.to_i }

# ["5.mp3", "10.mp3", "21.mp3", "40.mp3"]

ฉันใช้นิพจน์ทั่วไป (\d+ ) เพื่อให้ตรงกับตัวเลขแล้วจึงได้หมายเลขแรก (first ) &แปลงเป็นวัตถุจำนวนเต็ม (to_i )

วิธีการจัดเรียงแฮชใน Ruby

คุณไม่ได้จำกัดแค่การเรียงลำดับอาร์เรย์ คุณยังสามารถจัดเรียงแฮชได้

ตัวอย่าง :

hash = {coconut: 200, orange: 50, bacon: 100}

hash.sort_by(&:last)

# [[:orange, 50], [:bacon, 100], [:coconut, 200]]

สิ่งนี้จะจัดเรียงตามค่า แต่สังเกตเห็นสิ่งที่น่าสนใจที่นี่ สิ่งที่คุณได้รับกลับไม่ใช่แฮช

คุณจะได้รับอาร์เรย์หลายมิติเมื่อจัดเรียงแฮช

หากต้องการเปลี่ยนกลับเป็นแฮช คุณสามารถใช้วิธี Array#to_h

การจัดเรียงตามค่าหลายค่า

คุณอาจต้องการจัดเรียงบางอย่างตามแอตทริบิวต์หลายรายการ หมายความว่าคุณต้องจัดเรียงตามวันที่ก่อน (เช่น) แต่เนื่องจากคุณมีหลายอย่างที่มีวันที่เดียวกัน คุณจึงมีความสัมพันธ์กัน

คุณสามารถใช้แอตทริบิวต์รองเพื่อทำลายเน็คไทได้

ตัวอย่าง :

Event = Struct.new(:name, :date)
events = []

events << Event.new("book sale", Time.now)
events << Event.new("course sale", Time.now)
events << Event.new("new subscriber", Time.now)
events << Event.new("course sale", Time.now + 1.day)

events.sort_by { |event| [event.date, event.name] }

กุญแจสำคัญคืออาร์เรย์ภายใน sort_by บล็อก

โดยที่คุณตั้งค่าแอตทริบิวต์การเรียงลำดับหลักเป็นองค์ประกอบแรกของอาร์เรย์ (event.date ) &จากนั้นแอตทริบิวต์ tie-breaker รอง (event.name )

การใช้งาน QuickSort

เพื่อความสนุก ลองใช้วิธีการจัดเรียงของเราเอง วิธีนี้จะช้ากว่าวิธีการจัดเรียงที่มีอยู่แล้ว แต่ก็ยังเป็นแบบฝึกหัดที่น่าสนใจหากคุณชอบวิทยาการคอมพิวเตอร์

def quick_sort(list)
  return [] if list.empty?

  groups = list.group_by { |n| n <=> list.first }

  less_than    = groups[-1] || []
  first        = groups[0]  || []
  greater_than = groups[1]  || []

  quick_sort(less_than) + first + quick_sort(greater_than)
end

p quick_sort [3, 7, 2, 1, 8, 12]

# [1, 2, 3, 7, 8, 12]

แนวคิดของการเรียงลำดับอย่างรวดเร็วคือสุ่มเลือกหมายเลขหนึ่งแล้วแบ่งรายการที่เราจัดเรียงเป็นสองกลุ่ม

กลุ่มหนึ่งคือตัวเลขที่น้อยกว่าตัวเลขที่เลือก และอีกกลุ่มคือตัวเลขที่มากกว่าตัวเลขที่เลือก

จากนั้นเราก็ทำซ้ำการดำเนินการนี้จนกว่าจะจัดเรียงรายการ

เกณฑ์มาตรฐาน

เรามาดูกันว่าวิธีการจัดเรียงเหล่านี้เปรียบเทียบกันอย่างไรในแง่ของประสิทธิภาพ

ทับทิม 2.4.0 :

  sort!:                1405.8 i/s
  sort:                 1377.6 i/s - same-ish: difference falls within error
  sort_by reverse:      196.6  i/s - 7.15x  slower
  sort_by:              183.7  i/s - 7.65x  slower
  sort_by minus:        172.3  i/s - 8.16x  slower
  sort with block:      164.1  i/s - 8.57x  slower

อย่างที่คุณเห็น sort . ปกติ วิธีการเร็วกว่า sort_by . มาก แต่จะไม่ยืดหยุ่นเท่าเว้นแต่คุณจะใช้การบล็อก

วิดีโอ

สรุป

คุณได้เรียนรู้วิธีใช้ sort &sort_by วิธีการจัดเรียงอาร์เรย์และแฮชในรูปแบบต่างๆ คุณยังได้เรียนรู้เกี่ยวกับความแตกต่างด้านประสิทธิภาพและวิธีการใช้อัลกอริธึม Quicksort

นี่คือสิ่งที่คุณควรจำ :

  • คุณสามารถใช้ sort เมธอดบนอาร์เรย์ แฮช หรือออบเจกต์ที่นับได้อื่นๆ &คุณจะได้รับพฤติกรรมการเรียงลำดับเริ่มต้น (เรียงตาม <=> โอเปอเรเตอร์)
  • คุณสามารถใช้ sort ด้วยบล็อกและอาร์กิวเมนต์สองบล็อก เพื่อกำหนดว่าวัตถุหนึ่งแตกต่างจากวัตถุอื่นอย่างไร (บล็อกควรคืนค่า 1, 0 หรือ -1)
  • คุณสามารถใช้ sort_by ด้วยบล็อกและหนึ่งอาร์กิวเมนต์ เพื่อกำหนดหนึ่งแอตทริบิวต์สำหรับแต่ละอ็อบเจ็กต์ซึ่งจะใช้เป็นพื้นฐานสำหรับการเรียงลำดับ (ความยาวอาร์เรย์ คุณลักษณะของอ็อบเจ็กต์ ดัชนี ฯลฯ) บล็อกควรคืนค่าจำนวนเต็มที่กำหนดตำแหน่งของวัตถุในอาร์เรย์ที่จัดเรียง

อย่าลืม แชร์โพสต์นี้ เพื่อให้ผู้คนสามารถเรียนรู้ได้มากขึ้น 🙂