- Java: can iterate over elements in an array without
using an index:
foreach (ItemType item: someArray)
{
item.print();
}
- One difference for Ruby: arrays can have different types of items:
messed_up = [42, 'why?', ['avogadro', 6.02214086e23], nil]
- How to iterate over arrays?
- A block: a sequence of actions between curly braces
- They can also be between do and end, but curlies
are good for now
- Executing a block: yield
- Example:
def do_twice
yield
yield
end
do_twice { puts "echo" }
- More general example:
def doit_again(n)
for i in 1..n
yield
end
end
doit_again(10) { puts "bye" }
- Each time yield executed, executes corresponding block
- yield can take parameters:
def doit_again(n)
i = 1
while i <= n
yield i
i += 1
end
end
doit_again(5) { |x| puts x**x }
- There's a simpler way: the .each operation on a range:
(1..5).each { puts "hello" }
- .each is essentially doit_again written as a member
of Array
- This is also overloaded to allow a block with a single parameter:
(1..5).each { |count| puts count }
- .each operation on an array sets up an iterator over all
elements; use a block to access each one:
words = ['fee', 'fi', 'fo', 'fum']
words.each { |it| puts it }
words.each { |it| puts it.reverse }
- .find: find first meeting some condition
words.find { |x| x.length == 2 }
- Creating an array by mapping operation over an existing array:
words.map { |w| w + "-" + w.upcase }
words
words.map! { |w| w + "-" + w.upcase }
words
- Select items matching a predicate:
words.select { |x| x.length > 5 }
- Note: Ruby programmers tend to use do/end for longer blocks:
words.map do |w|
tmp = w.downcase
puts "Lower case word: #{tmp}"
end
but curly braces are better in some editors (you get matching) and are good
enough for this course.