Ruby Enumerator

Code Block Syntax

values = [1, 4]
values.each { |x| print x }           # Single line statement

values.each { |x|                     # {}: Multiple line block
   print x
}

values.each do |x|                    # do end: multiple line block
   print x
end

Ruby Numeric Enumerator

0.upto(9) {|x| print x}    # From 0 up to 9: 0123456789

3.times {|x| print x}      # 3 iterations: 012

0.step(1, 0.1) do |x|
    print x                # From 0 to 1 with step 0.1: 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
end

Ruby equivalent of the for loop "for (i=0; i<count; i++)"

count = 5
0.upto(count) do |x|
  puts x
end

Ruby Collection Enumerator

Iterate through each Ruby object elements: each

[1,2,3].each {|x| print x }   # 123
(1..3).each  {|x| print x }   # 123

{:one=> 'a', :two=> 'b'}.each do |key,value|   # two-b one-a
  print "#{key}-#{value} "
end

Iterate through Ruby object elements and return a collection of derived values: map/collect

square = [1,2,3].collect {|x| x*x} # [1,4,9]
square = [1,2,3].map {|x| x*x}     # [1,4,9]
words = ["hello", "world"]
result = words.map {|x| x.upcase }   # ["HELLO", "WORLD"]

Return an object with selected or rejected Ruby elements: select/reject

even = (1..10).select {|x| x%2 == 0} # [2,4,6,8,10]
odd  = (1..10).reject {|x| x%2 == 0} # [1,3,5,7,9]

Apply an aggregate functions to all Ruby object elements

data    = [1, 2, 3]
total   = data.inject {|sum, x| sum + x }       # 1+2+3=6
prod    = data.inject(1.0) {|p,x| p*x }         # 1.0*1*2*3 = 6
maximum = data.inject do |max,x|
  max>x ? max : x                               # 3
end
sum = 0
[1, 2, 3].each {|x| sum += x }
puts sum                                        # 6

Local variables (Ruby 1.9)

# Separate parameters |x;y| with ";" declare the variables local to the block only
x = 0
[1, 2, 3].each {|x;y| x += y}
puts x                                          # 0

Merge 2 Ruby object elements/collection: zip

(1..3).zip([4,5,6]) {|x| print x.inspect }      # zip merge top elements of the 2 objects and return as x
                                                # Prints "[1,4][2,5][3,6]"

Ruby File Enumerator

File.open(filename) do |f|
  f.each {|line| print line }             # Loop and print each line until eof
end

File.open(filename) do |f|
  f.each_with_index do |line, number|     # Each line and it's line number
    print "#{number}: #{line}"
  end
end

Implement Custom Enumerator

Call a caller code block n times

def sqLoop(n)
  while n > 0 do
    yield n, n*n                         # Call the code block with 2 parameters
    n = n - 1
  end
end

Call enumerator

sqLoop(5) {|x,y| print x, "-", y, " "}   # 5-25 4-16 3-9 2-4 1-1

Find the maximum of a collection

def find_max(v)
  length = v.length
  max = v[0]
  current = 1
  while current < length do
    max = yield max, v[current]          # Call the code block to see which is larger
    current += 1
  end
  max
end
data = [4, 5, 2, 9, 4]
max = find_max(data) {|m,x| m>x ? m : x }      # 9

Support a caller with or without a code block

def find_max(v)
  length = v.length
  max = v[0]
  current = 1
  while current < length do
    if (block_given?)                        # If the caller supply a code block
       max = yield max, v[current] if block_given?
    else                                     # If the caller has no code block
       max = max > v[current] ? max : v[current]
    end
    current += 1
  end
  max
end
max1 = find_max(data) {|m,x| m>x ? m : x }
max2 = find_max(data)                         # Call without a code block