The Iterator

Juan Carlos Hinojo
Purpose
Its a container interface capable of accessing in a secuential way a group of elements without exposing its primary source or representation.

Types of Iterators
External Iterator
Internal Iterator
Internal Iterator
.each
Internal Iterator
Iterator built-in the collection.
Iteration logic occurs inside the aggregate object.
You can pass code as a block which will be called for each element in the iteration.
[ 1, 3, 5 ].each { |i| puts i }
def fibUpTo(max)
i1, i2 = 1, 1
while i1 <= max
yield i1
i1, i2 = i2, i1+i2
end
end
fibUpTo(1000) { |f| print f, " " }
def threeTimes
yield
yield
yield
end
threeTimes { puts "Hello" }
External Iterator
@array = Array.new(array)
External Iterator
Iteration is dictated by an external class.
Iteration logic is separated into a different class.
- Handle multiple object types.
- More control over iteration
class ArrayIterator
def initialize(array)
@array = Array.new(array)
@index = 0
end
def has_next?
@index < @array.length
end
def next_item
value = @array[@index]
@index += 1
value
end
end
require './ArrayIterator'
i = ArrayIterator.new(['red', 'green', 'blue'])
while i.has_next?
puts "item: #{i.next_item}"
end
i = ArrayIterator.new('abc')
while i.has_next?
puts("item: #{i.next_item}")
end
Enumerable
include Enumerable
Enumerable
Module with built-in iterators
Must define a #each method
which yields each item in the
collection.
class Colors
include Enumerable
def each
yield "red"
yield "green"
yield "blue"
end
end
>> c = Colors.new
>> c.map { |i| i.reverse }
=> ["der", "neerg", "eulb"]
>> [1,2,3,4,5].select { |i| i > 3 }
=> [4,5]
class Portfolio
include Enumerable
def initialize
@accounts = []
end
def each(&block)
@accounts.each(&block)
end
def add_account(account)
@accounts << account
end
end
class Account
attr_accessor :name, :balance
def initialize(name, balance)
@name = name
@balance = balance
end
def <=>(other_account)
balance <=> other_account.balance
end
end
require './Account'
require './Portfolio'
portfolio = Portfolio.new
portfolio.add_account Account.new('red', 2000)
portfolio.add_account Account.new('blue', 1000)
portfolio.add_account Account.new('green', 500)
puts portfolio.any? { |account| account.balance > 2000 }
puts portfolio.all? { |account| account.balance >= 10 }
Lazy Iterator
(1..Float::INFINITY).lazy.select { |x| x % 2 == 0 }.first(100)
Resources
http://ruby-doc.com/docs/ProgrammingRuby/html/tut_containers.html
http://chickenriceplatter.github.io/blog/2013/04/07/internal-vs-external-iterators/
http://blog.carbonfive.com/2012/10/02/enumerator-rubys-versatile-iterator/
http://www.sitepoint.com/guide-ruby-collections-iii-enumerable-enumerator/
We are hiring =)


The Iterator
By Juan Carlos Hinojo
The Iterator
- 550