Last iteration condition

M

Mike

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

Phrogz

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
 
D

Devin Mullins

Phrogz said:
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.
 
G

Gary Wright

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
 
J

james.d.masters

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
 
L

Luis de la Rosa

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
 
L

L Forrister

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
 
G

Gary Wright


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
 
B

Brian Candler

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
 
G

Gary Wright

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

Robert Klemme

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.

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

Kind regards

robert
 
R

Robert Klemme

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.

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top