Bạn có thể sử dụng phương thức select trong Ruby để lọc một mảng các đối tượng.
Ví dụ, bạn có thể tìm tất cả các số chẵn trong một danh sách.
Nếu không dùng select, code sẽ trông như sau:
even_numbers = []
[1,2,3,4,5,6].each do |n|
if n.even?
even_numbers << n
end
end
even_numbers
Đó là khá nhiều code cho một việc đơn giản!
Hãy cùng tìm hiểu cách sử dụng select.
Ví dụ về phương thức Select
Sử dụng select yêu cầu một block.
Bên trong block, bạn phải trả về một giá trị đánh giá là true hoặc false, và select sẽ dùng điều đó để lọc mảng của bạn.
Bạn có thể tìm hiểu về giá trị boolean trong Ruby bằng cách đọc bài viết này.
Đây là một ví dụ:
[1,2,3,4,5,6].select { |n| n.even? }
Điều này sẽ làm tương tự như ví dụ đầu tiên ở phần giới thiệu, nhưng với ít code hơn nhiều.
Thực tế, chúng ta có thể rút gọn thêm nữa.
Như sau:
[1,2,3,4,5,6].select(&:even?)
Loại tắt này chỉ hoạt động khi bạn cần gọi một phương thức trực tiếp trên từng phần tử của mảng.
Bạn cũng có thể dùng select với hash.
Ví dụ:
stock = { apples: 10, oranges: 5, bananas: 1 }
stock.select { |k, v| v > 1 } # {:apples=>10, :oranges=>5}
Ở đây k đại diện cho key và v đại diện cho value.
Tức là:
"Tìm cho tôi tất cả các loại trái cây có số lượng tồn kho lớn hơn 1".
Kết hợp Select với các phương thức khác
Bạn có thể kết hợp phương thức select với một phương thức Enumerable khác.
Đáng chú ý nhất là with_index.
Ví dụ:
fruits = %w(apple orange banana)
fruits.select.with_index { |word, idx| idx.even? } # ["apple", "banana"]
Điều này cho phép bạn lọc bằng chỉ số (index), thay vì dùng chính đối tượng (trong trường hợp này là chuỗi).
Lọc mảng tại chỗ (In-Place)
Sử dụng select trên một mảng luôn tạo ra một mảng mới.
Nếu bạn muốn thay đổi mảng gốc, bạn có thể dùng phương thức select!.
Cách làm như sau:
fruits = %w(apple orange banana)
fruits.select! { |fruit| fruit.start_with? "a" } # ["apple"]
Các phương thức kết thúc bằng dấu chấm than (như select!) sẽ thay đổi đối tượng thay vì trả về đối tượng mới, nhưng quy tắc này không được ngôn ngữ bắt buộc.
Đó chỉ là một quy ước giữa chúng ta.
Find vs Select
select rất tốt khi bạn muốn lọc một danh sách và nhận được một mảng kết quả.
Nhưng nếu bạn chỉ muốn tìm một đối tượng duy nhất thì sao?
Bạn có thể dùng phương thức find.
Ví dụ:
letters = %w(a aa aaa aaaa)
letters.find { |l| l.size == 3 } # "aaa"
letters.find { |l| l.size == 10 } # nil
find trả về phần tử khớp đầu tiên, hoặc nil nếu không tìm thấy.
Hiểu về phương thức Find All
Nếu bạn đang thắc mắc về phương thức find_all và nó liên quan như thế nào đến find & select...
Rất đơn giản!
- Phương thức
find_alllà bí danh (alias) củaselect. - Phương thức
findgiúp bạn tìm một đối tượng cụ thể, thay vì nhiều đối tượng.
Ruby 2.6 thêm một bí danh khác cho select:
filter
Phương thức ngược lại của Select là gì?
Bạn có thể loại bỏ các phần tử không muốn thay vì chọn những phần tử bạn cần.
Dễ dàng với select:
[1,2,3,4,5,6].select { |n| n != 4 }
Nhưng có một phương thức làm cho việc này rõ ràng hơn.
Đó là phương thức reject.
Ví dụ:
[1,2,3,4,5,6].reject { |n| n == 4 }
Bạn không có lợi thế kỹ thuật nào về hiệu suất hay mặt khác, nhưng nó làm cho code của bạn tốt hơn.
Phương thức Select trong Rails
Tôi không muốn bạn bị nhầm lẫn khi làm việc với model Rails và biết rằng bạn cũng có thể dùng select ở đó.
Bạn nên biết rằng...
Phương thức select này là khác!
Ví dụ:
Fruit.select(:id, :name, :color)
Khi bạn dùng select với một model ActiveRecord, bạn đang yêu cầu các cột cụ thể từ cơ sở dữ liệu.
Theo hiểu biết của tôi, điều này chủ yếu được làm vì lý do hiệu suất.
Một lưu ý cuối cùng:
Nếu bạn đang làm việc với một mảng thông thường bên trong ứng dụng Rails, thì bạn đang dùng phương thức select mà chúng ta đã bàn论 suốt bài viết này.
Tóm tắt
Bạn đã học về select, một trong những phương thức hữu ích nhất của Ruby để làm việc với các tập hợp đối tượng như mảng, range và hash.

Bây giờ đến lượt bạn, hãy mở trình soạn thảo và thực hành ngay.
Cảm ơn bạn đã đọc!