Back to Home

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?