[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Last iteration condition

Mike

4/3/2007 2:56:00 AM

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.

12 Answers

Gavin Kistner

4/3/2007 3:09:00 AM

0

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

ri each_with_index

Devin Mullins

4/3/2007 3:48:00 AM

0

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.

Gary Wright

4/3/2007 4:18:00 AM

0


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

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




james.d.masters

4/3/2007 4:23:00 AM

0

On Apr 2, 7:56 pm, "Mike" <michae...@gmail.com> wrote:
> How could I know that current iteration is the last in the series?

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

Luis de la Rosa

4/3/2007 4:54:00 AM

0

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.luisde...

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.
>
>


L Forrister

4/3/2007 5:01:00 AM

0

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

[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

Brian Candler

4/3/2007 5:45:00 AM

0

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

Try thread around
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-...
for some sample implementations.

Gary Wright

4/3/2007 6:31:00 AM

0


On Apr 3, 2007, at 1:44 AM, Brian Candler wrote:
> Try thread around
> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-...
> 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
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




Brian Candler

4/3/2007 7:51:00 AM

0

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.

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

Gary Wright

4/3/2007 8:25:00 AM

0


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.