Collections, Blocks, and Iterators

Download Report

Transcript Collections, Blocks, and Iterators

CS 480/680 – Comparative Languages
Ruby Containers, Blocks, and
Iterators
Array Review
 Ruby arrays are collections of object references
 Arrays must be expressly created, but are
dynamically sized
• Undefined elements have the value nil, which also
equates to false
 Arrays are indexed with []
• First element is 0
• Negative numbers start at the end

array[-1] is the last element
 See array.rb
Blocks & Iterators
2
Useful array operators
 & – array intersection
• [ 1, 1, 3, 5 ] & [ 1, 2, 3 ]
» [1, 3]
 * – repetition
• [ 1, 2, 3 ] * 2
» [1, 2, 3, 1, 2, 3]
 + – concatenation
• [ 1, 2, 3 ] + [ 3, 4, 5 ]
» [1, 2, 3, 3, 4, 5]
 | – union
• [ 1, 2, 3 ] | [ 3, 4, 5 ]
» [1, 2, 3, 4, 5]
 delete
• a = [ 1, 2, 3, 3, 5 ]
a.delete(3)
a » [1, 2, 3, 3, 4, 5]
Blocks & Iterators
3
More useful array operators
 empty? – returns true if empty, else false
 index(c) – returns index of first element == c
 join – concatenates array elements into a string
•
•




[ 1, 2, 3].join
» “123”
[ 1, 2, 3].join(“-”)
» “1-2-3”
length – returns # elements
nitems – returns # non-nil elements
reverse, sort – return a reversed/sorted array
Many others in the Ruby book: Built-in
Classes and Methods/Array
Blocks & Iterators
4
Arrays as stacks and queues
 a.push(item) – add item to the end of an a
 a.pop – returns the last item of a, or nil if empty
 a.shift – returns and removes the first element
of a, shifts every other element down by one
 a.unshift(item) – prepends item to the start of a,
moving all elements up one index
 Stack – push & pop
 Queue – push & shift
Blocks & Iterators
5
Arrays as method parameters
 a = [1, 2, 3, 4, 5, ‘a’, ‘b’, ‘c’]
 someMethod(a) – passes one array argument
 someMethod(*a) – passes 8 parameters, the
elements of the array (expands the array)
 def someMethod(*a) … collect all the
parameters passed into array a
Blocks & Iterators
6
Hashes
 While the index to an array is an integer, the
index to a hash can be any type
• Some care must be taken here… more on that later
 A hash is essentially a list of key  value pairs
 No implicit ordering
• Can’t do stacks/queues
 Most common data structure in Ruby!
• h = { 'dog' => 'canine', 'cat' => 'feline', \
'donkey' => 'asinine' }
• h.length » 3
; h['dog'] » "canine"
Blocks & Iterators
7
Implementation Details
 See jukebox.rb
 Note:
• Functions that behave differently with different
types of arguments (similar to C++ overloading, but
implemented very differently)
• Use of blocks and iterators: @songs.find{}
• Array as a stack/queue
Blocks & Iterators
8
Ruby Iterators
 An iterator in Ruby is a method that gets
passed a code block, and it runs that code block
on every element in a collection, and returns a
specific result
• Code blocks are enclosed in {}
• Parameters to code blocks are listed between |’s
Blocks & Iterators
9
Iterators for arrays
 See iterators.rb
 a.each – calls block once for each item in a,
passing the item as a parameter
 a.each_index – passes the index, not the item
 b = a.collect – calls block once for each item in
a, block’s return values are collected in b
 a.sort – optional block
 a.delete_if – block should return true or false
 a.find – return first element of array for which
block returns true
Blocks & Iterators
10
Writing your own iterators
 An iterator is simply a method that calls a block
of code, possibly passing parameters
 Example: Given a chunk of code, execute it
three times.
 Solution:
• C/C++ maybe possible with function pointers
• Ruby: def threeTimes
Blocks & Iterators
Call any block
yield
passed to this
yield
method.
yield
end
threeTimes { puts "Hello" }
11
Iterator Parameters
 Call any block of code, passing it each even
number up to n:
def evenUpTo(max)
i = 2
while i <= max
yield i
i *= 2
end
end
evenUpTo(1000) { |f| print f, " " }
Blocks & Iterators
12
Another example
 The find() method for class SongList might be
implemented like this:
class SongList
def find
for i in 0...songs.size
title = songs[i].name
return title if yield(title)
end
return nil
end
end
# Find first song title starting with ‘A’:
myList.find {|title| title[0,1] == ‘A’ }
Blocks & Iterators
13
Last iterator example
 Iterators are very useful in file I/O:
f = File.open("testfile")
f.each {|line|
print line
}
f.close
Blocks & Iterators
14
Blocks
 Ruby style programming uses blocks and
iterators as often as possible
 Blocks cannot use an explicit return()
statement, the last value calculated in the block
is the return value
 Blocks can be specified between {}’s or
between a do and end pair
Blocks & Iterators
15
Blocks for transactions
 If File.open is passed a block, it will…
• Open the file
• Call the block, passing it the opened file object
• Close the file when the block exits
File.open("testfile") do |f|
f.each {|line|
print line
end
Blocks & Iterators
16
Exercises
 Write a simple RPN calculator, using an array as a
stack, and only dealing with operators +, -, *, and /
 Write a subroutine (method) that takes a variable
number of arguments and prints them all to standard
out
 Write a program that uses array.collect to look at an
array, and copy every element divisible by three into a
new array
 Write an iterator for your student class that returns an
array of each test score that passes a test – the test is
the block for the iterator and should return true or
false. Call the iterator collect_exams_if
Blocks & Iterators
17