# Last iteration condition

Hi,

How could I know that current iteration is the last in the series?
For example:

[1, 2, 3, 4, 5, 3, 4].each do |element|
print element.to_s
print ',' if !LAST
end

P.S. This is just an example. I don't want to use "join". My program
logic is much complicated than this example.

Thank you.

ri each_with_index

···

On Apr 2, 8:56 pm, "Mike" <michae...@gmail.com> wrote:

How could I know that current iteration is the last in the series?
For example:

[1, 2, 3, 4, 5, 3, 4].each do |element|
print element.to_s
print ',' if !LAST
end

Here are a couple of ideas:

require 'generator'
require 'enumerator'

a = [1,2,3,4]
g = Generator.new(a)

while g.next?
item = g.next
if g.next?
puts "#{item} is not the last item"
else
puts "#{item} is the last item"
end
end

a = [5,6,7,8]
a.push(final = Object.new)

Enumerable::Enumerator.new(a).each_cons(2) do |a, b|
if b == final
puts "#{a} is the last item"
else
puts "#{a} is not the last item"
end
end

# Gary Wright

···

On Apr 2, 2007, at 11:00 PM, Mike wrote:

Hi,

How could I know that current iteration is the last in the series?
For example:

[1, 2, 3, 4, 5, 3, 4].each do |element|
print element.to_s
print ',' if !LAST
end

a = [1, 2, 3, 4, 5, 3, 4]
a.each_with_index do |element,i|
print element.to_s
print ',' if i == a.length - 1
end

···

On Apr 2, 7:56 pm, "Mike" <michae...@gmail.com> wrote:

How could I know that current iteration is the last in the series?

Try this. It should print out "1,2,3,4,5,3,4" as desired.

arr = [1, 2, 3, 4, 5, 3, 4]
arr.each_with_index do |element, index|
print element.to_s
print "," unless arr.length == index + 1
end

Cheers,
Luis
http://www.luisdelarosa.com

···

On Apr 2, 2007, at 11:00 PM, Mike wrote:

Hi,

How could I know that current iteration is the last in the series?
For example:

[1, 2, 3, 4, 5, 3, 4].each do |element|
print element.to_s
print ',' if !LAST
end

P.S. This is just an example. I don't want to use "join". My program
logic is much complicated than this example.

Thank you.

[1, 2, 3, 4, 5, 3, 4].each_index do |index|
print ',' if index > 0
print element[index].to_s
#-- or -- if the logic "print ',' " is actually dependent on the
values of the elements
print element[index-1].to_s
end

~~LF

···

On 4/2/07, Mike <michaelst@gmail.com> wrote:

How could I know that current iteration is the last in the series?
[1, 2, 3, 4, 5, 3, 4].each do |element|
print element.to_s
print ',' if !LAST
end

for some sample implementations.

···

On Tue, Apr 03, 2007 at 12:00:09PM +0900, Mike wrote:

How could I know that current iteration is the last in the series?
For example:

[1, 2, 3, 4, 5, 3, 4].each do |element|
print element.to_s
print ',' if !LAST
end

Then *what* is your logic? What are you trying to achieve?

Kind regards

robert

···

On 03.04.2007 04:56, Mike wrote:

How could I know that current iteration is the last in the series?
For example:

[1, 2, 3, 4, 5, 3, 4].each do |element|
print element.to_s
print ',' if !LAST
end

P.S. This is just an example. I don't want to use "join". My program
logic is much complicated than this example.

Phrogz wrote:

···

On Apr 2, 8:56 pm, "Mike" <michae...@gmail.com> wrote:

How could I know that current iteration is the last in the series?
[1, 2, 3, 4, 5, 3, 4].each do |element|

ri each_with_index

You might also wanna restructure it as
arr[0..-2].each(&blah); bloo[arr.last]
depending on the logic at hand.

Building off of Brian's suggestion in that thread, here
is a way to provide a 'countdown' as the end of the iteration
approaches. Default is to only flag the last item but you
can ask for any number of items to be flagged.

This is the first time I've found a need for the numeric return
value of nonzero?

module Enumerable
def each_with_countdown(count=0)
queue = []
each_with_index do |item,index|
if index > (count)
yield queue.shift, true
end
queue.push(item)
end
queue.each_with_index do |item, index|
yield item, (count - index).nonzero?
end
end

[1,2,3,4,5,6].each_with_countdown(3) { |item, more|
case more
when TrueClass
puts "#{item}"
when 3
puts "#{item}, next to next to next to last item!"
when 2
puts "#{item}, next to next to last item!"
when 1
puts "#{item}, next to last item!"
when NilClass
puts "#{item}, last item"
end
}

[1,2,3,4,5,6].each_with_countdown(1) { |item, more|
puts "#{item}, more: #{more.inspect}"
}

[1].each_with_countdown { |item, more|
puts "#{item}, more: #{more.inspect}"
}

StringIO.new("line1\nline2\nline3").each_with_countdown do |line, more|
if more
puts line
else
puts "last: #{line}"
end
end

Gary Wright

···

On Apr 3, 2007, at 1:44 AM, Brian Candler wrote:

for some sample implementations.

Interesting. Maybe it would be cleaner to return nil for all non-countdown
items, and then n-1, n-2 ... 0 as the flag (or n, n-1 ... 1). e.g.

require 'stringio'
module Enumerable
def each_with_countdown(count=1)
queue = []
each do |item|
queue.push(item)
yield queue.shift, nil if queue.size > count
end
queue.each_with_index do |item, index|
yield item, count - index - 1
end
end
end

[1,2,3,4,5,6].each_with_countdown(3) { |item, rem|
case rem
when nil
puts "#{item}"
when 2
puts "#{item}, next to next to last item!"
when 1
puts "#{item}, next to last item!"
when 0
puts "#{item}, last item"
end
}

[1,2,3,4,5,6].each_with_countdown(1) { |item, rem|
puts "#{item}, rem: #{rem.inspect}"
}

[1].each_with_countdown { |item, rem|
puts "#{item}, rem: #{rem.inspect}"
}

StringIO.new("line1\nline2\nline3").each_with_countdown do |line, rem|
if rem
puts "last: #{line}"
else
puts line
end
end

···

On Tue, Apr 03, 2007 at 03:31:09PM +0900, Gary Wright wrote:

Building off of Brian's suggestion in that thread, here
is a way to provide a 'countdown' as the end of the iteration
approaches. Default is to only flag the last item but you
can ask for any number of items to be flagged.

I like this solution! Thank you.

···

On 4/3/07, Gary Wright <gwtmp01@mac.com> wrote:

On Apr 3, 2007, at 1:44 AM, Brian Candler wrote:
> for some sample implementations.

Building off of Brian's suggestion in that thread, here
is a way to provide a 'countdown' as the end of the iteration
approaches. Default is to only flag the last item but you
can ask for any number of items to be flagged.

This is the first time I've found a need for the numeric return
value of nonzero?

module Enumerable
def each_with_countdown(count=0)
queue = []
each_with_index do |item,index|
if index > (count)
yield queue.shift, true
end
queue.push(item)
end
queue.each_with_index do |item, index|
yield item, (count - index).nonzero?
end
end

[1,2,3,4,5,6].each_with_countdown(3) { |item, more|
case more
when TrueClass
puts "#{item}"
when 3
puts "#{item}, next to next to next to last item!"
when 2
puts "#{item}, next to next to last item!"
when 1
puts "#{item}, next to last item!"
when NilClass
puts "#{item}, last item"
end
}

[1,2,3,4,5,6].each_with_countdown(1) { |item, more|
puts "#{item}, more: #{more.inspect}"
}

[1].each_with_countdown { |item, more|
puts "#{item}, more: #{more.inspect}"
}

StringIO.new("line1\nline2\nline3").each_with_countdown do |line, more|
if more
puts line
else
puts "last: #{line}"
end
end

Gary Wright

I liked the idea of the flag being true for all but the last item.
It just makes boolean expressions nicer for that special case even
when you are counting down.

···

On Apr 3, 2007, at 3:50 AM, Brian Candler wrote:

On Tue, Apr 03, 2007 at 03:31:09PM +0900, Gary Wright wrote:

Building off of Brian's suggestion in that thread, here
is a way to provide a 'countdown' as the end of the iteration
approaches. Default is to only flag the last item but you
can ask for any number of items to be flagged.

Interesting. Maybe it would be cleaner to return nil for all non-countdown
items, and then n-1, n-2 ... 0 as the flag (or n, n-1 ... 1). e.g.

No need for complex new code, this can be done with #inject very simply:

irb(main):005:0> print "back ", %w{aaa bbb ccc ddd}.inject {|x,y| print "front ", x, "\n"; y}, "\n"
front aaa
front bbb
front ccc
back ddd
=> nil

The trick is to use the form without arguments.

Kind regards

robert

···

On 03.04.2007 10:24, Gary Wright wrote:

On Apr 3, 2007, at 3:50 AM, Brian Candler wrote:

On Tue, Apr 03, 2007 at 03:31:09PM +0900, Gary Wright wrote:

Building off of Brian's suggestion in that thread, here
is a way to provide a 'countdown' as the end of the iteration
approaches. Default is to only flag the last item but you
can ask for any number of items to be flagged.

Interesting. Maybe it would be cleaner to return nil for all non-countdown
items, and then n-1, n-2 ... 0 as the flag (or n, n-1 ... 1). e.g.

I liked the idea of the flag being true for all but the last item.
It just makes boolean expressions nicer for that special case even
when you are counting down.