Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implementation and test of Enumerable#with_position
- Loading branch information
Showing
2 changed files
with
100 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
|
||
module Enumerable | ||
class Position | ||
def initialize | ||
@first = true | ||
@last = false | ||
end | ||
|
||
def after_first! | ||
@first = false | ||
end | ||
|
||
def at_end! | ||
@last = true | ||
end | ||
|
||
def first? | ||
@first | ||
end | ||
|
||
def middle? | ||
not (@first or @last) | ||
end | ||
|
||
def last? | ||
@last | ||
end | ||
end | ||
|
||
# Allows one to know the position of the enumeration easily. | ||
# | ||
# 5.times.collect.with_position do |i, position| | ||
# $stdout.write "#{i}#{position.middle? ? ',' : ''}" | ||
# end | ||
# | ||
# Where this becomes more useful, is when it's easy to determine the position of elements, e.g. | ||
# | ||
# 10.times.select(&:odd?).with_position{|n,p| ... } | ||
# | ||
def with_position | ||
return to_enum(:with_position) unless block_given? | ||
|
||
position = Position.new | ||
|
||
while item = self.next | ||
begin | ||
self.peek | ||
rescue StopIteration | ||
position.at_end! | ||
end | ||
|
||
yield item, position.dup | ||
|
||
position.after_first! | ||
end | ||
rescue StopIteration | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
covers 'facets/enumerable/with_position' | ||
|
||
test_case Enumerable do | ||
|
||
method :with_position do | ||
|
||
test do | ||
a = 5.times.with_position.to_a | ||
|
||
item, position = a.first | ||
item.assert == 0 | ||
assert position.first? | ||
refute position.middle? | ||
refute position.last? | ||
|
||
|
||
item, position = a[2] | ||
item.assert == 2 | ||
assert position.middle? | ||
refute position.first? | ||
refute position.last? | ||
|
||
item, position = a.last | ||
item.assert == 4 | ||
refute position.first? | ||
refute position.middle? | ||
assert position.last? | ||
end | ||
|
||
test do | ||
a = 1.times.with_position.to_a | ||
|
||
item, position = a.first | ||
item.assert == 0 | ||
assert position.first? | ||
refute position.middle? | ||
assert position.last? | ||
end | ||
|
||
end | ||
|
||
end |