Enumerable#grep
The next Enumerable method we'll take a look at is grep. This method allows us to filter elements from a collection based on a pattern:
log_lines = [
"ERROR: Disk space low",
"INFO: User logged in",
"WARNING: High memory usage",
"ERROR: Network timeout",
"INFO: File uploaded",
"INFO: User logged out",
]
errors = log_lines.grep(/ERROR/)
# => ["ERROR: Disk space low", "ERROR: Network timeout"]
authentication = log_lines.grep(/logged/)
# => ["INFO: User logged in", "INFO: User logged out"]
const logLines = [
"ERROR: Disk space low",
"INFO: User logged in",
"WARNING: High memory usage",
"ERROR: Network timeout",
"INFO: File uploaded",
"INFO: User logged out",
];
const errors = logLines.filter(line => /ERROR/.test(line));
// => ["ERROR: Disk space low", "ERROR: Network timeout"]
const authentication = logLines.filter(line => /logged/.test(line));
// => ["INFO: User logged in", "INFO: User logged out"]
Though I personally only reach for grep when doing Regexp filtering, the grep method can also match on anything that responds to the === operator:
values = [1, "two", 3.0, 4.0, "five", 6]
integers = values.grep(Integer)
# => [1, 6]
strings = values.grep(String)
# => ["two", "five"]
measurements = [1, 2.5, 3, 4.75, 5, 3.14, 2.0, 2.16]
between_three_and_five = measurements.grep(3..5)
# => [3, 4.75, 5, 3.14]
const values = [1, "two", 3.0, 4.0, "five", 6];
const integers = values.filter(v => Number.isInteger(v));
// => [1, 6]
const strings = values.filter(v => typeof v === "string");
// => ["two", "five"]
const measurements = [1, 2.5, 3, 4.75, 5, 3.14, 2.0, 2.16];
const betweenThreeAndFive = measurements.filter(v => v >= 3 && v <= 5);
// => [3, 4.75, 5, 3.14]
If you provide a block to grep, it will act like map, transforming each matched element:
words = %w[apple banana apricot blueberry cherry]
a_words_upcased = words.grep(/^a/, &:upcase)
# => ["APPLE", "APRICOT"]
b_word_lengths = words.grep(/^b/, &:length)
# => [6, 9]
const words = ["apple", "banana", "apricot", "blueberry", "cherry"];
const aWordsUpcased = words
.filter(word => /^a/.test(word))
.map(word => word.toUpperCase());
// => ["APPLE", "APRICOT"]
const bWordLengths = words
.filter(word => /^b/.test(word))
.map(word => word.length);
// => [6, 9]
There is also grep_v, which works just like grep -v does on the command line, returning the elements that do not match the pattern.
The grep method has been part of Enumerable since at least Ruby 1.6, released in 2000, and as such belongs to the oldest parts of the Ruby standard library. In his Euroko 2025 Keynote, Ruby's creator Yukihiro "Matz" Matsumoto described Ruby as "object oriented UNIX". That heritage is clearly visible in this method.