Hãy nói về phương thức grep.
Phương thức này làm gì cho bạn?
Bạn dùng Grep để lọc object enumerable, như Arrays và Ranges.
"Nhưng select đã làm thế rồi!"
Đúng, nhưng grep hoạt động khác và cho kết quả khác.
Hãy xem ví dụ.
Ví dụ Ruby Grep Method
Cho mảng này:
objects = ["a", "b", "c", 1, 2, 3, nil]
Bạn dùng grep lấy chỉ string:
objects.grep(String) # ["a", "b", "c"]
Chỉ Integer:
objects.grep(Integer) # [1, 2, 3]
Hoặc mọi thứ không phải nil:
objects.grep_v(NilClass) # ["a", "b", "c", 1, 2, 3]
Nếu bạn có mảng từ:
fruit = ["apple", "orange", "banana"]
Bạn tìm tất cả từ bắt đầu bằng "a":
fruit.grep(/^a/) # ["apple"]
Hoặc kết thúc bằng "e":
fruit.grep(/e$/) # ["apple", "orange"]
Và nếu có danh sách số:
numbers = [9, 10, 11, 20]
Bạn lấy tất cả số trong range:
numbers.grep(5..10) # [9, 10]
Bạn kết hợp map và select thành một khi dùng block:
numbers.grep(5..10) { |n| n * 2 } # [18, 20]
Nếu muốn fancy…
times_two = ->(x) { x * 2 }
numbers.grep(5..10, ×_two) # [18, 20]
Khá cool, phải không?
Grep vs Select: Hiểu sự khác biệt
Grep hoạt động như thế nào?
Bí mật nằm ở phương thức === (triple equals) trong Ruby.
Grep gọi phương thức này trên đối số bạn truyền.
Và ra là class, regex và range đều implement ===.
Chúng implement phương thức này theo cách hợp lý cho class.
Ví dụ:
- Class (như
IntegerhoặcArray), so sánh với class của object cho trước. - Range check số có trong range không.
- Regex check có match không.
Vậy khi bạn nói:
objects.grep(Integer)
Bạn thực sự nói:
objects.select { |obj| Integer === obj }
Lâu nay tôi băn khoăn về grep…
Cho đến khi hiểu điều này.
Phương thức select lọc list dựa trên kết quả block.
Nếu block evaluate true, element đó được chọn.
Nhưng grep chỉ so sánh hai thứ dùng ===.
Bạn có thể nói grep là phiên bản chuyên biệt hơn của select!
Ruby Grep Mindmap

Xem Video hướng dẫn
Tóm tắt
Bạn đã học về phương thức grep trong Ruby! Nó rất hữu ích khi bạn hiểu cách hoạt động.
Hãy practice để kiến thức thấm sâu.
Practice là chìa khóa mastery!