วันนี้คุณจะได้เรียนรู้วิธีจัดการกับกริดใน Ruby โดยใช้วิธีทรานสโพสของ Ruby
ลองนึกภาพว่าคุณมีตารางที่สมบูรณ์แบบ สมมติว่าสี่เหลี่ยมจัตุรัส 3×3 ในรูปแบบของอาร์เรย์หลายมิติ
และคุณต้องการนำแถวและแปลงเป็นคอลัมน์ .
ทำไมคุณถึงอยากทำอย่างนั้น
ใช้ครั้งเดียวสำหรับเกมคลาสสิค:tic-tac-toe
คุณเก็บกระดานของคุณเป็นตาราง จากนั้นเพื่อหาจังหวะที่ชนะ คุณต้องตรวจสอบ แถว , คอลัมน์ &เส้นทแยงมุม .
ปัญหาคือหากคุณจัดเก็บกริดเป็นอาร์เรย์ คุณจะสามารถเข้าถึงแถวได้โดยตรงเท่านั้น
คอลัมน์ The Hard Way
โดย "การเข้าถึงโดยตรง" ฉันหมายความว่าคุณสามารถข้ามอาร์เรย์ของคุณ (ด้วย each
, map
ฯลฯ) โดยไม่ต้องใช้การจัดทำดัชนีอาร์เรย์มากเกินความจำเป็น
มาดูตัวอย่างกัน!
นี่คือตาราง :
grid = [ [1,2,3], [4,5,6], [7,8,9] ]
นี่คือภาพที่ฉันทำขึ้นเพื่อคุณ :
คุณสามารถรับคอลัมน์โดยอ้างอิงดัชนี
ตัวอย่างเช่น คอลัมน์แรกจะเป็น :
[grid[0][0], grid[1][0], grid[2][0]] # [1, 4, 7]
แต่แถวแรกมีแค่นี้ :
grid[0] # [1, 2, 3]
เราจะทำให้การทำงานกับคอลัมน์ง่ายเหมือนการทำงานกับแถวได้อย่างไร
คอลัมน์ วิธีง่ายๆ
วิธีง่ายๆ ในการทำเช่นนี้คือการใช้วิธี Array#transpose
ตัวอย่าง :
columns = grid.transpose
ใช่ นั่นคือทั้งหมดที่คุณต้องทำ!
ตอนนี้คุณสามารถรับคอลัมน์แรกดังนี้:
columns[0] # [1, 4, 7]
อย่างที่คุณเห็นการรู้วิธีการมากมายสามารถช่วยคุณประหยัดเวลาได้มาก 🙂
ทิก-แทค-โท
ฉันจะไม่อธิบายเรื่องทั้งหมด ฉันแค่ต้องการแสดงให้คุณเห็นว่าวิธีนี้ใช้กับโครงการจริงได้อย่างไร
ในการชนะเกมโอเอกซ์ คุณต้องกรอกแถว คอลัมน์ หรือแนวทแยง
นี่คือรหัสสำหรับตรวจสอบแถว :
def check_rows @board.each { |row| return row.first if all_equal?(row) } end
และนี่คือรหัสสำหรับคอลัมน์ :
def check_columns @board.transpose.each { |row| return row.first if all_equal?(row) } end
สังเกตว่าความแตกต่างเพียงอย่างเดียวคือ transpose
วิธีการ!
นี่คือ all_equal?
วิธีการ:
def all_equal?(row) return if row.first == nil row.each_cons(2).all? { |x,y| x == y } end
คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับวิธีการ each_cons นั้นได้โดยอ่านโพสต์นี้เกี่ยวกับวิธีการที่นับได้
สรุป
คุณได้เรียนรู้เกี่ยวกับวิธีการทรานสโพสแล้ว
ด้วยตารางที่สมบูรณ์แบบ transpose ช่วยให้คุณแปลงแถวเป็นคอลัมน์เพื่อให้เข้าถึงได้ง่าย
หากคุณชอบโพสต์นี้ คุณอาจต้องการพิจารณาซื้อหนังสือ Ruby Deep Dive ของฉัน