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

สไลซ์และลูกเต๋าแจกแจงนับทับทิม

วันนี้เราจะมาพูดถึง slice_before , slice_when และ slice_after . นี่เป็นวิธีที่มีประโยชน์มากเมื่อคุณต้องการจัดกลุ่มรายการในอาร์เรย์หรือที่นับได้อื่น ๆ ตามเกณฑ์ที่กำหนดเอง

คุณคงคุ้นเคยกับ Array#slice . ช่วยให้คุณสามารถดึงชุดย่อยของอาร์เรย์ตามช่วงของดัชนีได้:

a = ["a", "b", "c"]
a.slice(1, 2)
# => ["b", "c"]

สิ่งนี้มีประโยชน์ แต่ไม่สามารถใช้กับตัวนับได้ เนื่องจากตัวนับไม่มีดัชนี

slice_before , slice_when และ slice_after เมธอดไม่ต้องพึ่งพาดัชนี ดังนั้นคุณสามารถใช้กับดัชนีใดก็ได้ มาดูกัน!

การใช้ Enumerable#slice_before

Enumerable#slice_before แยกและนับออกเป็นกลุ่ม ณ จุดก่อนทำการแข่งขัน

การแข่งขันจะทำผ่าน === โอเปอเรเตอร์ ซึ่งหมายความว่าคุณสามารถจับคู่ทุกสิ่งได้

ค่าที่ตรงกัน

คุณสามารถจับคู่ค่าเดียว ที่ควรจะเป็นที่ชัดเจน :)

a = ["a", "b", "c"]
a.slice_before("b").to_a
# => [["a"], ["b", "c"]]

การจับคู่นิพจน์ทั่วไป

คุณสามารถใช้นิพจน์ทั่วไปสำหรับการจับคู่ข้อความที่ซับซ้อนมากขึ้น

a = ["000", "b", "999"]
a.slice_before(/[a-z]/).to_a
# => [["000"], ["b", "999"]]

ช่วงที่ตรงกัน

หากคุณกำลังทำงานกับตัวเลข คุณสามารถแบ่งอาร์เรย์ตามช่วงได้

a = [100, 200, 300]
a.slice_before(150..250).to_a
# => [[100], [200, 300]]

การจับคู่คลาส

อันนี้อาจดูแปลกสำหรับคุณเล็กน้อย แต่ก็สอดคล้องกับพฤติกรรมของ === อย่างเต็มที่ โอเปอเรเตอร์

a = [1, "200", 1.3]
a.slice_before(String).to_a
# => [[1], ["200", 1.3]]

การใช้บล็อก

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

a = [1, 2, 3, 4, 5]
a.slice_before do |item|
  item % 2 == 0
end
# => [[1], [2, 3], [4, 5]]

การใช้ Enumerable#slice_after

Enumerable#slice_after ทำงานเหมือนกับ Enumerable#slice_before ยกเว้นว่าสไลซ์จะเกิดขึ้นหลังการแข่งขัน ไปคิด :-)

a = ["a", "b", "c"]
a.slice_after("b").to_a
# => [["a", "b"], ["c"]]

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

ใช้ Enumerable#slice_when

Enumerable#slice_when เป็นสัตว์ร้ายที่แตกต่างจาก slice_before และ slice_after . แทนที่จะจับคู่รายการเดียวในอาร์เรย์ คุณจะจับคู่รายการที่อยู่ติดกัน

ซึ่งหมายความว่าคุณสามารถจัดกลุ่มรายการตาม "ขอบ" ระหว่างรายการได้

ตัวอย่างเช่น ที่นี่เราจัดกลุ่มรายการตาม "ความใกล้เคียง" กับรายการที่อยู่ติดกัน

a = [1, 2, 3, 100, 101, 102]

# Create a new group when the difference 
# between two adjacent items is > 10.
a.slice_when do |x, y| 
  (y - x) > 10
end
# => [[1, 2, 3], [100, 101, 102]]

หากคุณสนใจที่จะเรียนรู้เพิ่มเติม โปรดดู Ruby Docs สำหรับ slice_when . พวกเขามีตัวอย่างโค้ดที่ยอดเยี่ยมหลายประการ

อาร์เรย์เทียบกับตัวนับ

ฉันได้ใช้อาร์เรย์ในตัวอย่างส่วนใหญ่ข้างต้น เนื่องจากอาร์เรย์เข้าใจง่าย คุณควรจำไว้ว่าคุณสามารถใช้ slice_before . ได้ , slice_when และ slice_after กับจำนวนใด ๆ

ตัวอย่างเช่น หากคุณมีไฟล์ที่มีอีเมลจำนวนมาก คุณสามารถแยกอีเมลแต่ละฉบับโดยใช้ slice_before . รหัสด้านล่างนำมาจากเอกสาร

open("mbox") { |f|
  f.slice_before { |line|
    line.start_with? "From "
  }.each { |mail|
    puts mail
  }

และโปรดสังเกตว่าเมธอดสไลซ์ไม่ส่งคืนอาร์เรย์ พวกเขาส่งคืนจำนวนนับ นั่นหมายความว่าคุณสามารถใช้ map , each และวิธีการแจกแจงอื่น ๆ ที่คุณชื่นชอบบน. เฮ็คคุณสามารถแยกได้อีก :)