Iterators

Ref. WGR Section 6.3, "Iterators and code blocks"

Loops as Methods

times is on your side

potatoes = nil
3.times do |i|
  potatoes = i+1
  puts "#{potatoes} potato"
end
puts potatoes + 1

prints

1 potato
2 potato
3 potato
4

implementing times using until

def times x
  i = 0
  until i == x
    yield i
    i += 1
  end
  x
end

(times returns the number itself)

to each his own

    ["apple", "banana", "cherry"].each do |fruit|
      puts "I love #{fruit}!"
    end

warning: each returns the collection, not the value

def count_chars a
  c = 0
  a.each do |s|
    c += s.length   # this returns c
  end               # but this returns a
  c                 # so this returns c (again)
end

count_chars ["apple", "banana", "cherry"]
=> 17

implementing each using until

def each a
  i = 0
  until i == a.size
    yield a[i]
    i += 1
  end
  a
end

the map is not the territory

["apple", "banana", "cherry"].map do |fruit|
  fruit.reverse
end
=> ["elppa", "ananab", "yrrehc"]

implementing map using each

def map input
  a = []
  input.each do |item|
    a << yield(item)
  end
  a
end

Other Awesome Iterators

Ref. Using Select Etc.

lethal injection

inject example

  class Array
    def sum
      self.inject(0) do |total, current| 
        total + current
      end
    end
  end

  [1,2,3].sum #=> 6

inject reduced

You can also send inject (or reduce) the name of a method only:

class Array
  def sum
    self.reduce(:+)
  end
end

[1,2,3].sum #=> 6

Here we are "reducing" the array by calling + on all its elements in succession.

more help

 Previous Lesson Next Lesson 

Outline

[menu]

/