In the Ruby Silver exam, questions like “Choose methods with the same behavior” frequently appear. Here’s a summary of such methods.
The
find_all
method collects elements that meet a condition. It iterates through the block with the element as the block argumentitem
, and collects elements where the block returns true into an array. Theselect
method is an alias forfind_all
.
# Collect integers from 1 to 30 that are divisible by 7.
# Using select
irb(main):001:0> p (1..30).select { |n| n % 7 == 0 }
[7, 14, 21, 28]
=> [7, 14, 21, 28]
# Using find_all
irb(main):003:0> p (1..30).find_all { |n| n % 7 == 0 }
[7, 14, 21, 28]
=> [7, 14, 21, 28]
The
collect
method iterates through the block for each element, creating and returning an array of the block’s return values. The block argumentitem
contains each element. Themap
method is an alias forcollect
.
# Create an array by converting hexadecimal strings to numbers.
# Using collect
irb(main):001:0> numbers = ["68", "65", "6C", "6C", "6F"]
=> ["68", "65", "6C", "6C", "6F"]
irb(main):002:0> p numbers.collect { |item| item.to_i(16) }
[104, 101, 108, 108, 111]
=> [104, 101, 108, 108, 111]
# Using map
irb(main):003:0> p numbers.map { |item| item.to_i(16) }
[104, 101, 108, 108, 111]
=> [104, 101, 108, 108, 111]
The
find
method searches for and retrieves an element. It iterates through the block with the element as the block argumentitem
, and returns the element when the block returns true. If all block returns are false, it returnsnil
. Thedetect
method is an alias forfind
.
# Find numbers divisible by 5 in an array.
# Using find
irb(main):001:0> numbers = [15, 55, 89, 99, 121, 134]
=> [15, 55, 89, 99, 121, 134]
irb(main):002:0> numbers.find {|item| item % 5 == 0 }
=> 15
# Using detect
irb(main):001:0> numbers = [15, 55, 89, 99, 121, 134]
=> [15, 55, 89, 99, 121, 134]
irb(main):004:0> numbers.detect {|item| item % 5 == 0 }
=> 15
The
delete_if
method iterates through the block for each element, deleting elements where the block returns true. It modifies the receiver itself and always returns the receiver. Thereject!
method also iterates through the block for each element, deleting elements where the block returns true. However, its return value differs: it returns the receiver if deletions occurred, andnil
if no changes were made.
# Using delete_if
irb(main):001:0> fruits = ["apple", "orange", "banana", "kiwi", "peach", "endoumame", "strawberry"]
=> ["apple", "orange", "banana", "kiwi", "peach", "endoumame", "strawberry"]
# Delete elements where the first character matches `aiueo`
irb(main):002:0> fruits.delete_if {|item| item =~ /^[aiueo]/ }
=> ["banana", "kiwi", "peach", "strawberry"]
# Using reject!
irb(main):001:0> fruits = ["apple", "orange", "banana", "kiwi", "peach", "endoumame", "strawberry"]
=> ["apple", "orange", "banana", "kiwi", "peach", "endoumame", "strawberry"]
# Delete elements where the first character matches `aiueo`
irb(main):002:0> fruits.reject! {|item| item =~ /^[aiueo]/ }
=> ["banana", "kiwi", "peach", "strawberry"]