Almighty Enumerable
Date: Jan 17, 2015
Enumerable is actually a 'Module'. What this means is that it is just a bunch of methods packaged together that can (and do) get "mixed in", or "included", with other classes just like Array [] and Hash {}. As long as the class like to work with Enumerable and has own 'each' method to work with, Enumerable is simply do all the magics for a programmer.
Enumerable provides several searching methods and ability to sort. Enumerable also provides methods like #max, #min or #sort to compare elements. Pretty neat, huh?
To use these methods, the collection must implement <=> operator, as these methods rely on an ordering between numbers of the collection.
arr = %w[Ryan Sarah Brian Bob]
# %w is really cool trick. This will put " " in every element
arr.max { |x, y| x.length <=> y.length}
=>"Sarah"
#This will return same value as
arr.max_by { |x| x.length}
The only requirement for Enumerable to work with a class is 'each' iterator. #each is an iterator method that comes pre-packaged with the Array and Hash and other classes. It will allow whatever you pass in right side of stuff goes through "each" item in the object you called it on and passes it to the block that you specified.
Here is some examle of 'each' iterator
animal = ['dog', 'cat', 'cow', 'rabbit'].each { |a| print a + " "}
=> dog cat cow rabbit
Some Enumerable has built in 'each' so it can go through each element's numerical position
animal = ['dog, 'cat', 'cow', 'rabbit']
animal.each_with_index { |x, y| puts x if y % 2== 0}
=> dog
=> cow
There are three really cool Enumerable methods that I would like to focus on - map, group_by and cycle.
MAP
#map returns a new array filled with whatever gets returned by the block each time it runs.
animal = ['dog, 'cat', 'cow', 'rabbit']
my_fav_animal = animal.each_with_index.map { |x, y| x if y % 2== 0}
=> ["dog", nil, "cow", nil]
#collect do EXACTLY same as #map. It will returns a new array
animal = ['dog, 'cat', 'cow', 'rabbit']
my_fav_animal = animal.each_with_index.collect { |x, y| x if y % 2== 0}
=> ["dog", nil, "cow", nil]
GROUP_BY
#group_by { |obj| block } returns a hash {key, value array}
keys are the evaluated results from the block
values are arrays of elements in the collection that corrrespond to the key
[3,4,5].group_by { |x| x% 2 }
=> {1=>[3, 5], 0=>[4]}
[1,2,3, "apple"].group_by {|x| x.class}
=> {Fixnum=>[1, 2, 3], String=>["apple"]}
group = ["sarah", "ryan", "brian"]
=> {5=>["sarah", "brian"], 4=>["ryan"]}
CYCLE.. The Endless Journey
#cycle calls block for each element of enum "repeatedly" n times or forever if none or nil is given. Note that if a non-positive number is given or the collection is empty, it does nothing. Returns nil if the loop has finished without getting interrupted.
["dog", "cat", "cow"].cycle {|x| print x + " " }
dog cat cow dog cat cow dog cat cow.... forever..
["dog", "cat", "cow"].cycle(3) {|x| print x + " " }
dog cat cow dog cat cow dog cat cow => nil
["dog", "cat", "cow"].cycle(3) {|x| print x + " " }
=> nil
[].cycle(3) {|x| print x }
=> nil
FizzBuzz Game!!
def super_fizzbuzz(array)
array.map do |x|
if x%15==0
"FizzBuzz"
elsif x%5==0
"Buzz"
elsif x%3==0
"Fizz"
else
x
end
end
end
p super_fizzbuzz([1,2,3]) #=> [1,2, "Fizz"]
p super_fizzbuzz([1,2,5]) # => [1, 2, "Buzz"]
p super_fizzbuzz([1,2,15]) # => [1, 2, "FizzBuzz"]
Enumerator is a powerful tool. The methods that are part of Enumerable rely on the "each" method to work. It is also note-worthy that some methods are destructive, some are non-destructive and some offers both. Like map and map! returns same values but map! will change the original argument to the returned value. Some methods return true or false like none? or one?
Enumerable is actually a 'Module'. What this means is that it is just a bunch of methods packaged together that can (and do) get "mixed in", or "included", with other classes just like Array [] and Hash {}. As long as the class like to work with Enumerable and has own 'each' method to work with, Enumerable is simply do all the magics for a programmer.
Enumerable provides several searching methods and ability to sort. Enumerable also provides methods like #max, #min or #sort to compare elements. Pretty neat, huh?
To use these methods, the collection must implement <=> operator, as these methods rely on an ordering between numbers of the collection.
The only requirement for Enumerable to work with a class is 'each' iterator. #each is an iterator method that comes pre-packaged with the Array and Hash and other classes. It will allow whatever you pass in right side of stuff goes through "each" item in the object you called it on and passes it to the block that you specified.
Here is some examle of 'each' iterator
Some Enumerable has built in 'each' so it can go through each element's numerical position
There are three really cool Enumerable methods that I would like to focus on - map, group_by and cycle.
MAP
#map returns a new array filled with whatever gets returned by the block each time it runs.
#collect do EXACTLY same as #map. It will returns a new array
GROUP_BY
#group_by { |obj| block } returns a hash {key, value array}
CYCLE.. The Endless Journey
#cycle calls block for each element of enum "repeatedly" n times or forever if none or nil is given. Note that if a non-positive number is given or the collection is empty, it does nothing. Returns nil if the loop has finished without getting interrupted.
Enumerator is a powerful tool. The methods that are part of Enumerable rely on the "each" method to work. It is also note-worthy that some methods are destructive, some are non-destructive and some offers both. Like map and map! returns same values but map! will change the original argument to the returned value. Some methods return true or false like none? or one?