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

7 ตัวอย่างโค้ด Ruby ที่นักพัฒนาต้องดู

วิธีหนึ่งในการเรียนรู้เทคนิค รูปแบบ และเมธอด Ruby ใหม่ๆ คือการอ่านโค้ดที่คนอื่นเขียน

แต่คุณหา โค้ดที่น่าสนใจและ值得อ่าน ได้ที่ไหน?

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

ในบทความนี้:

ผมรวบรวม 7 ตัวอย่างที่ผมคิดว่าคุณจะชอบ

ผมจะให้ความคิดเห็นบนแต่ละตัวอย่างด้วย เพื่อช่วยให้คุณได้ประโยชน์สูงสุด

ผลรวมของสองตัวเลข

ในตัวอย่างนี้ เราต้องการทราบว่า ถ้ากำหนดอาร์เรย์ของตัวเลขที่ไม่ซ้ำกัน มีการรวมกันของสองตัวเลขที่ผลรวมเท่ากับตัวเลขเป้าหมายหรือไม่

โค้ด:

def sum_eq_n?(arr, n)
  return true if arr.empty? && n == 0
  arr.product(arr).reject { |a,b| a == b }.any? { |a,b| a + b == n }
end

นี่น่าสนใจเพราะผมใช้เมธอด product ที่นี่

เมื่อคุณใช้เมธอดนี้ มันเหมือนมีลูปซ้อนลูปที่รวมค่าทั้งหมดในอาร์เรย์ A กับค่าทั้งหมดในอาร์เรย์ B

นับ Mapping และการค้นหา

สมมติว่าคุณต้องการหาตัวเลขที่หายไปในลำดับเลขคณิต เช่น (2,4,6,10)

เราสามารถใช้กลยุทธ์ที่คำนวณความต่างระหว่างตัวเลข

[2, 2, 4]

เป้าหมายที่นี่คือการค้นหาว่าลำดับคืออะไร

มันเพิ่มขึ้นหรือลดลง?

เพิ่มขึ้นเท่าไหร่?

โค้ดนี้เผยลำดับ:

differences = [2, 2, 4]
differences.max_by { |n| differences.count(n) } # 2
# นี่คือการเพิ่มขึ้นระหว่างตัวเลขในลำดับ

เมื่อเรารู้ลำดับแล้ว เราสามารถเปรียบเทียบตัวเลขทั้งหมดเพื่อหาตัวที่หายไป

โค้ดที่นี่:

def find_missing(sequence)
  consecutive = sequence.each_cons(2)
  differences = consecutive.map { |a,b| b - a }
  sequence = differences.max_by { |n| differences.count(n) }
  missing_between = consecutive.find { |a,b| (b - a) != sequence }
  missing_between.first + sequence
end

find_missing([2,4,6,10]) # 8

นับดูว่าเราใช้เมธอด Ruby กี่ตัวที่ทำงานหนักให้เรา 🙂

ตัวอย่าง Regular Expression

ถ้าคุณทำงานกับสตริงและต้องการหาแพทเทิร์น Regular expressions คือเพื่อนของคุณ

มันอาจลำบากหน่อยที่จะทำให้ถูกต้อง แต่วิธีฝึกทำให้เก่ง!

ตอนนี้:

สมมติว่าเราต้องการทราบว่าสตริงที่กำหนดปฏิบัติตามแพทเทิร์นของ ตัวอักษรสระ (VOWEL) ถึง ตัวอักษรไม่ใช่สระ (NON-VOWEL) หรือไม่

แบบนี้:

"ateciyu"

เราสามารถใช้ regular expression ร่วมกับเมธอด match? เพื่อค้นหาได้

ตัวอย่างโค้ด:

def alternating_characters?(s)
  type = [/[aeiou]/, /[^aeiou]/].cycle
  if s.start_with?(/[^aeiou]/)
    type.next
  end
  s.chars.all? { |ch| ch.match?(type.next) }
end

alternating_characters?("ateciyu") # true

สังเกตบางอย่าง:

  1. เราใช้เมธอด cycle เพื่อสลับไปมาระหว่าง regex สระ และ regex ไม่ใช่สระ
  2. เราแปลงสตริงเป็นอาร์เรย์ตัวอักษรด้วย chars เพื่อใช้เมธอด all?

ตัวอย่าง Recursion และ Stack

Recursion (การเรียกซ้ำ) คือเมื่อเมธอดเรียกตัวเองหลายครั้งเป็นวิธีก้าวหน้าสู่คำตอบ

ปัญหาที่น่าสนใจหลายอย่างสามารถ แก้ได้ด้วย recursion

แตเพราะ recursion มีขีดจำกัด คุณสามารถใช้โครงสร้างข้อมูล stack แทนได้

ตอนนี้:

มาดูตัวอย่างที่เราต้องการหา "Power Set" ของอาร์เรย์ที่กำหนด Power Set คือเซตของทุก subset ที่สามารถสร้างจากอาร์เรย์ได้

ตัวอย่างด้วย recursion:

def get_numbers(list, index = 0, taken = [])
  return [taken] if index == list.size
  get_numbers(list, index+1, taken) + get_numbers(list, index+1, taken + [list[index]])
end

get_numbers([1,2,3])

ปัญหาเดียวกันแก้ด้วย stack:

def get_numbers_stack(list)
  stack = [[0, []]]
  output = []
  until stack.empty?
    index, taken = stack.pop
    next output << taken if index == list.size
    stack.unshift [index + 1, taken]
    stack.unshift [index + 1, taken + [list[index]]]
  end
  output
end

ไอเดียคือ ในแต่ละรอบของอัลกอริทึม เรา either เลือกตัวเลข หรือไม่เลือก

เราแยกกิ่ง และลองทั้งสองผลลัพธ์ เพื่อ สร้างทุกการรวมเป็นไปได้

นึกภาพต้นไม้ที่ใบแต่ละใบคือหนึ่งในคำตอบ

สังเกตบางอย่าง:

  1. คำตอบ recursion สั้นกว่า
  2. ส่วน "การก้าวหน้า" จริงของอัลกอริทึม (index + 1) เกือบเหมือนกัน
  3. Stack ที่เราใช้คือแค่อาร์เรย์ เพราะ Ruby ไม่มีคลาส Stack

ตัวอย่าง Method Chaining

นี่คือตัวอย่างโปรดของผม เพราะมันแสดงให้เห็นว่า Ruby อันทรงพลังแค่ไหน

การรวมเมธอดช่วยให้คุณ นำเอาต์พุตที่ผลิตโดยเมธอดหนึ่งไปต่อให้อีกเมธอด

เหมือนสายการผลิตโรงงาน!

คุณเริ่มต้นด้วยวัตถุดิบ (input) แล้วผ่านกระบวนการเรียกเมธอดเหล่านี้ คุณเปลี่ยนวัตถุดิบให้กลายเป็นผลลัพธ์ที่ต้องการอย่างช้าๆ

ตัวอย่าง:

def longest_repetition(string)
  max = string
    .chars
    .chunk(&:itself)
    .map(&:last)
    .max_by(&:size)
  max ? [max[0], max.size] : ["", 0]
end

longest_repetition("aaabb") # ["a", 3]

เมื่อได้รับสตริง โค้ดนี้จะหา ตัวอักษรที่ซ้ำต่อเนื่องกันยาวที่สุด

หมายเหตุ:

  • โค้ดจัดรูปแบบเพื่อเพิ่มความอ่านง่ายสูงสุด
  • การใช้รูปแบบ Symbol#to_proc (&:size)

ก็อีกอย่าง อย่าสับสนกับ "Law of Demeter"

"กฎ" นั้นเกี่ยวกับการเข้าถึงภายในของออบเจ็กต์อื่น

ที่นี่เราแค่แปลงออบเจ็กต์

ตัวอย่าง With Index

คุณอยากได้ดัชนีปัจจุบันขณะวนลูปคอลเลกชันไหม?

คุณสามารถใช้เมธอด with_index ได้

ตัวอย่าง:

def reverse_alternate(string)
  string.gsub(/[^\s]+/).with_index { |w, idx| idx.even? ? w : w.reverse }
end

reverse_alternate("Apples Are Good") # "Apples erA Good"

สังเกต:

  • เรารวม with_index และ even? เพื่อหาว่าต้องกลับคำปัจจุบันหรือไม่
  • Gsub โดยไม่มีบล็อกคืนค่าออบเจ็กต์ Enumerator ซึ่งช่วยให้คุณเชน (chain) กับเมธอดอื่นได้

ตัวอย่าง Each With Object

เมธอดน่าสนใจอีกตัวคือ each_with_object และเพื่อนของมัน with_object

คุณสามารถใช้สองเมธอดนี้เมื่อคุณต้องการออบเจ็กต์เพื่อเก็บผลลัพธ์

ตัวอย่าง:

def clean_string(str)
  str
    .chars
    .each_with_object([]) { |ch, obj| ch == "#" ? obj.pop : obj << ch }
    .join
end

clean_string("aaa#b")

ในตัวอย่างนี้ เราต้องการลบตัวอักษรสุดท้ายเมื่อเจอสัญลักษณ์ #

สังเกต:

  • each_with_object รับอาร์กิวเมนต์ ซึ่งคือออบเจ็กต์ที่เราต้องการเริ่มต้น อาร์กิวเมนต์นี้กลายเป็นพารามิเตอร์บล็อกตัวที่ 2
  • เราแปลงสตริงเป็นอาร์เรย์ตัวอักษร (chars) และกลับเป็นสตริงเมื่อเสร็จ (join)
  • เราใช้ ternary operator เพื่อตัดสินใจ ทำให้โค้ดสั้นลง

สรุป

ในบทความนี้ คุณได้เห็นตัวอย่างโค้ดน่าสนใจบางอย่างพร้อมความคิดเห็นและคำอธิบายของผม เพื่อช่วยให้คุณเขียนโค้ด Ruby ได้ดีขึ้น

อย่าลืมแชร์บทความนี้เพื่อให้คนอื่นเพลิดเพลินไปกับมัน

ขอบคุณที่อ่านครับ!