Hôm nay bạn sẽ học cách xử lý lưới (grid) trong Ruby dùng phương thức transpose.
Hãy tưởng tượng bạn có lưới hoàn hảo, ví dụ vuông 3x3, dưới dạng mảng đa chiều.
Và bạn muốn lấy hàng & chuyển thành cột.
Tại sao muốn làm vậy?
Một ứng dụng là trò chơi kinh điển: tic-tac-toe (cờ ca rô).
Bạn lưu bàn cờ như lưới. Sau đó tìm nước đi thắng cần kiểm tra hàng, cột & đường chéo.
Vấn đề là nếu lưu lưới như mảng bạn chỉ truy cập trực tiếp hàng.
Cột cách khó
Bằng “truy cập trực tiếp” tôi muốn nói bạn duyệt mảng (với each, map, v.v.) không cần index mảng nhiều hơn cần thiết.
Xem ví dụ!
Đây là lưới:
grid = [ [1,2,3], [4,5,6], [7,8,9] ]
Đây là hình ảnh minh họa:

Bạn có thể lấy cột bằng tham chiếu index.
Ví dụ, cột đầu tiên:
[grid[0][0], grid[1][0], grid[2][0]] # [1, 4, 7]
Nhưng hàng đầu chỉ là:
grid[0] # [1, 2, 3]
Làm sao làm việc với cột dễ như hàng?
Cột cách dễ
Cách dễ là dùng Array#transpose.
Ví dụ:
columns = grid.transpose
Vâng, chỉ cần vậy!
Bây giờ lấy cột đầu:
columns[0] # [1, 4, 7]
Như bạn thấy biết nhiều phương thức tiết kiệm nhiều công sức 🙂
Tic-Tac-Toe
Tôi không giải thích toàn bộ. Chỉ muốn chỉ cách phương thức này áp dụng cho dự án thực.
Để thắng tic-tac-toe cần lấp đầy hàng, cột hoặc đường chéo.
Mã kiểm tra hàng:
def check_rows
@board.each { |row| return row.first if all_equal?(row) }
end
Mã kiểm tra cột:
def check_columns
@board.transpose.each { |row| return row.first if all_equal?(row) }
end
Chú ý khác biệt duy nhất là phương thức transpose!
Đây là all_equal?:
def all_equal?(row)
return if row.first == nil
row.each_cons(2).all? { |x,y| x == y }
end
Bạn học thêm về each_cons đọc bài Enumerable methods.
Tóm tắt
Bạn đã học phương thức transpose.
Cho lưới hoàn hảo, transpose cho phép biến hàng thành cột để truy cập dễ dàng.
Nếu thích bài này bạn có thể cân nhắc mua sách Ruby Deep Dive của tôi.