0Pricing
Ruby Academy · บทเรียน

ตัววนซ้ำแบบขี้เกียจ

การประเมินผลแบบขี้เกียจ

ตัววนซ้ำแบบขี้เกียจ เป็นบทเรียน Ruby Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Ruby Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Ruby Academy มีบทเรียนทั้งหมด 4 บทเรียน

การประเมินแบบเลื่อนเวลา

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

result = (1..Float::INFINITY).lazy.map { |n| n * 2 }.first(5)
p result

ปัญหาของเมธอดแบบประเมินทันที

การเรียก map กับช่วงที่ไม่มีที่สิ้นสุดโดยไม่ใช้ lazy จะไม่มีวันเสร็จสิ้น เพราะมันพยายามสร้างอาร์เรย์ผลลัพธ์ทั้งหมดให้เสร็จก่อน

# Eager version would hang. Lazy completes instantly:
first_three = (1..Float::INFINITY).lazy.select(&:even?).first(3)
p first_three

สร้างตัวแจงนับแบบประเมินเมื่อจำเป็น

เรียก .lazy กับสิ่งใดก็ตามที่รองรับการวนซ้ำ เพื่อรับเวอร์ชันแบบประเมินเมื่อจำเป็น เมธอดที่ต่อกันหลังจากนั้นจะทำงานในรูปแบบเดียวกัน

lazy = (1..10).lazy
puts lazy.class

จะยังไม่ทำงานจนกว่าจะสั่งให้ประเมิน

สายการเรียกแบบประเมินเมื่อจำเป็นจะสร้างสูตรการทำงานไว้ แต่ยังไม่ลงมือทำ เมธอดปลายทางอย่าง first, to_a หรือ force จะเป็นตัวเริ่มการทำงาน

chain = (1..Float::INFINITY).lazy.map { |n| n * n }
puts "Nothing computed yet"
p chain.first(4)

บังคับให้สร้างผลลัพธ์

force (ชื่อเรียกอีกชื่อคือ to_a) จะทำให้สายการทำงานแบบประเมินเมื่อจำเป็นที่มีขอบเขต กลายเป็นอาร์เรย์

result = (1..20).lazy.select(&:odd?).first(5)
p result
all = (1..6).lazy.map { |n| n * 10 }.force
p all

ต่อการทำงานแบบประเมินเมื่อจำเป็น

การดำเนินการแบบประเมินเมื่อจำเป็นหลายรายการจะสอดแทรกกันทีละองค์ประกอบ แทนที่จะทำงานแยกกันเป็นรอบเต็ม ๆ แต่ละค่าจะไหลผ่านสายการทำงานทั้งหมดก่อนจะเริ่มค่าถัดไป

result = (1..Float::INFINITY)
  .lazy
  .map { |n| n * n }
  .select { |n| n.even? }
  .first(4)
p result

take และหยุดขณะเงื่อนไขเป็นจริง

take และ take_while แบบประเมินเมื่อจำเป็นจะหยุดดึงค่าเมื่อเงื่อนไขของตนเป็นจริง

result = (1..Float::INFINITY).lazy.take_while { |n| n < 6 }.to_a
p result

ลำดับข้อมูลที่ไม่มีที่สิ้นสุด

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

naturals = Enumerator.new do |y|
  n = 1
  loop { y << n; n += 1 }
end
p naturals.lazy.map { |x| x * 3 }.first(5)

ประหยัดหน่วยความจำ

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

big = (1..1_000_000).lazy
first_match = big.select { |n| n % 7 == 0 && n % 11 == 0 }.first
puts first_match

ควรใช้การประเมินเมื่อจำเป็นเมื่อใด

ใช้การประเมินเมื่อจำเป็นเมื่อ:

  • แหล่งข้อมูลไม่มีที่สิ้นสุดหรือมีขนาดใหญ่มาก
  • คุณต้องการผลลัพธ์เพียงไม่กี่รายการ
  • คุณต้องการหลีกเลี่ยงอาร์เรย์ระหว่างกลางขนาดใหญ่

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

fizz = (1..Float::INFINITY).lazy.select { |n| n % 3 == 0 }.first(5)
p fizz

นำทุกอย่างมารวมกัน

ตัวแจงนับแบบประเมินเมื่อจำเป็นจะเลื่อนการทำงานออกไป:

  • .lazy ทำให้สายการทำงานเป็นแบบประเมินเมื่อจำเป็น
  • การทำงานจะเริ่มขึ้นเมื่อเมธอดปลายทางดึงค่า
  • เหมาะอย่างยิ่งกับลำดับข้อมูลขนาดใหญ่หรือไม่มีที่สิ้นสุด
squares = (1..Float::INFINITY).lazy.map { |n| n * n }
p squares.select(&:odd?).first(4)

ตรวจสอบความเข้าใจ

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

ทบทวน

คุณได้เรียนรู้เกี่ยวกับตัวแจงนับแบบประเมินเมื่อจำเป็น:

  • .lazy เลื่อนการคำนวณออกไป
  • เมธอดปลายทาง (first, to_a, force) จะเริ่มการทำงาน
  • แต่ละค่าจะไหลผ่านสายการทำงานทั้งหมดเมื่อจำเป็น
  • เหมาะสำหรับลำดับข้อมูลขนาดใหญ่หรือไม่มีที่สิ้นสุด
p (1..Float::INFINITY).lazy.select(&:even?).map { |n| n + 1 }.first(3)

คำถามที่พบบ่อย

บทเรียน “ตัววนซ้ำแบบขี้เกียจ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัววนซ้ำแบบขี้เกียจ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Ruby Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Ruby Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัววนซ้ำแบบขี้เกียจ”

การประเมินผลแบบขี้เกียจ คุณปฏิบัติ Ruby Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Ruby Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Ruby Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “ตัววนซ้ำแบบขี้เกียจ” ใช้เวลานานแค่ไหน

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

ฉันเขียนและรันโค้ดในบทเรียน Ruby Academy นี้ได้ไหม

ได้ บทเรียน Ruby Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การเขียน each แบบกำหนดเอง
  2. การรวม Enumerable
  3. ตัววนซ้ำแบบขี้เกียจ
  4. ออบเจ็กต์ Enumerator
← กลับไปที่ Ruby Academy