คุณสามารถใช้เมธอด select ใน Ruby เพื่อกรองอาร์เรย์ของออบเจ็กต์ได้
ตัวอย่างเช่น คุณสามารถหา หมายเลขคู่ทั้งหมดในรายการได้
หากไม่ใช้ select โค้ดจะมีลักษณะดังนี้:
even_numbers = []
[1,2,3,4,5,6].each do |n|
if n.even?
even_numbers << n
end
end
even_numbers
โค้ดเยอะมากสำหรับสิ่งที่ง่ายขนาดนี้!
มาเรียนรู้วิธีใช้ select กัน
ตัวอย่างเมธอด Select
การใช้ select ต้องการบล็อก (block)
ภายในบล็อก คุณต้องคืนค่าที่ประเมินเป็น true หรือ false และ select จะใช้ค่านั้นในการกรองอาร์เรย์ของคุณ
คุณสามารถเรียนรู้เกี่ยวกับค่าบูลีนใน Ruby ได้จากบทความนี้
นี่คือตัวอย่าง:
[1,2,3,4,5,6].select { |n| n.even? }
สิ่งนี้จะทำงานเหมือนตัวอย่างแรกในบทนำ แต่ด้วยโค้ดน้อยลงมาก
จริงๆ แล้วเราสามารถลดรูปได้อีก
แบบนี้:
[1,2,3,4,5,6].select(&:even?)
เทคนิคทางลัดแบบนี้ใช้งานได้ก็ต่อเมื่อคุณต้องเรียกเมธอดโดยตรงบนทุกองค์ประกอบของอาร์เรย์เท่านั้น
ก็อีกอย่าง คุณยังสามารถใช้ select กับแฮช (hash) ได้อีกด้วย
ตัวอย่าง:
stock = { apples: 10, oranges: 5, bananas: 1 }
stock.select { |k, v| v > 1 } # {:apples=>10, :oranges=>5}
ที่ k แทนคีย์ (key) และ v แทนค่า (value)
กล่าวง่ายๆ คือ:
"หาผลไม้ทั้งหมดที่มีสต็อกมากกว่า 1 ให้ฉัน"
การรวม Select กับเมธอดอื่นๆ
คุณสามารถรวมเมธอด select กับเมธอด Enumerable อื่นๆ ได้
ที่น่าสนใจที่สุดคือ with_index
ตัวอย่าง:
fruits = %w(apple orange banana)
fruits.select.with_index { |word, idx| idx.even? } # ["apple", "banana"]
สิ่งนี้ช่วยให้คุณกรองโดยใช้ดัชนี (index) แทนที่จะใช้ออบเจ็กต์เอง (ในกรณีนี้คือสตริง)
การกรองอาร์เรย์แบบ In-Place
การใช้ select บนอาร์เรย์จะสร้างอาร์เรย์ใหม่เสมอ
หากคุณต้องการเปลี่ยนอาร์เรย์ต้นฉบับแทน คุณสามารถใช้เมธอด select! ได้
วิธีทำ:
fruits = %w(apple orange banana)
fruits.select! { |fruit| fruit.start_with? "a" } # ["apple"]
เมธอดที่ลงท้ายด้วยเครื่องหมายคำติ (เช่น select!) จะเปลี่ยนออบเจ็กต์โดยตรงแทนที่จะคืนออบเจ็กต์ใหม่ แต่นี่เป็นเพียงข้อตกลงระหว่างนักพัฒนา ไม่ได้ถูกบังคับโดยภาษา Ruby เอง
Find vs Select
select เหมาะสำหรับการกรองรายการและได้อาร์เรย์ผลลัพธ์
แต่ถ้าคุณต้องการหาเพียงออบเจ็กต์เดียว?
คุณสามารถใช้เมธอด find ได้
เช่นนี้:
letters = %w(a aa aaa aaaa)
letters.find { |l| l.size == 3 } # "aaa"
letters.find { |l| l.size == 10 } # nil
find จะคืนค่าตัวแรกที่ตรงตามเงื่อนไข หรือ nil หากไม่พบ
การทำความเข้าใจเมธอด Find All
หากคุณสงสัยเกี่ยวกับเมธอด find_all และว่ามันเกี่ยวข้องกับ find และ select อย่างไร...
มันง่ายมาก!
- เมธอด
find_allเป็นอีเลียส (alias) ของselect - เมธอด
findช่วยค้นหาออบเจ็กต์เฉพาะตัวเดียว แทนที่จะเป็นหลายตัว
Ruby 2.6 เพิ่มอีเลียสอีกตัวสำหรับ select:
filter
ค่าตรงข้ามของ Select คืออะไร?
คุณสามารถลบองค์ประกอบที่ไม่ต้องการแทนที่จะเลือกสิ่งที่ต้องการ
ทำได้ง่ายกับ select:
[1,2,3,4,5,6].select { |n| n != 4 }
แต่มีเมธอดที่ทำให้โค้ดชัดเจนกว่า
เมธอดนั้นคือ reject
ตัวอย่าง:
[1,2,3,4,5,6].reject { |n| n == 4 }
ไม่มีข้อได้เปรียบทางเทคนิคด้านประสิทธิภาพหรืออื่นๆ แต่มันจะทำให้โค้ดของคุณดีขึ้น
เมธอด Select ใน Rails
ผมไม่อยากให้คุณสับสนเมื่อทำงานกับโมเดล Rails และรู้ว่าคุณสามารถใช้ select ได้ที่นั่นด้วย
คุณควรทราบว่า...
เมธอด select นี้ต่างจากที่เราพูดถึงกันไปแล้ว!
ตัวอย่าง:
Fruit.select(:id, :name, :color)
เมื่อคุณใช้ select กับโมเดล ActiveRecord คุณกำลังขอคอลัมน์เฉพาะจากฐานข้อมูล
据我所知 ทำเช่นนี้เพื่อเหตุผลด้านประสิทธิภาพเป็นหลัก
บันทึกสุดท้ายเรื่องนี้:
หากคุณทำงานกับอาร์เรย์ทั่วไปภายในแอป Rails คุณก็ใช้เมธอด select ที่เราพูดถึงกันตลอดบทความนี้อยู่ดี
สรุป
คุณได้เรียนรู้เกี่ยวกับ select หนึ่งในเมธอดที่มีประโยชน์ที่สุดของ Ruby สำหรับการทำงานกับคอลเลกชันของออบเจ็กต์ เช่น อาร์เรย์ ช่วง (ranges) และแฮช

ตอนนี้ถึงคุณแล้ว ลองเปิดเอดิเตอร์และนำไปใช้งานดูสิ
ขอบคุณที่อ่านครับ!