 # Fixnum, range and array into one single loop?

Hi,
I’m struggeling with writing a little script. It has a loop just e.g.
like this:

for x in 1…10 do
begin
puts “#{x}”
end

The userinput is the loop count (so above the userinput would have been
1…10): but now this userinput can be a fixnum like 12 or 36 or it can
be a range like 1…10 or 24…84 or an array like [23,41,35,63] and for
every 3 different input kinds the loop shall do the same.

Like in this example:

If userinput is just fixnum 11 it just prints 11 on the screen, is it a
range from 1…10 all numbers from 1…10 shall be printed and for an
array all single numbers stored in the array…you know what I mean. The
actual routine doesn’t print anything it’s just about I have to process
numbers which can the user give in, in three different ways and I was
wondering if it is possible to build this into one single loop and not
three different ones?

greets

``````                        (
)
(
/\  .-"""-.  /\
//\\/  ,,,  \//\\
|/\| ,;;;;;, |/\|
//\\\;-"""-;///\\
//  \/   .   \/  \\
(| ,-_| \ | / |_-, |)
//`__\.-.-./__`\\
// /.-(() ())-.\ \\
(\ |)   '---'   (| /)
` (|           |) `
jgs     \)           (/
``````

one must still have chaos in oneself to be able to give birth to a
dancing star

On 06.05.2007 15:20, anansi wrote:

1…10): but now this userinput can be a fixnum like 12 or 36 or it can
wondering if it is possible to build this into one single loop and not
three different ones?

def my_loop(x,&b)
case x
when /\A\d+\z/
x.to_i.times(&b)
when /\A(\d+)…(\d+)\z/
(\$1.to_i … \$2.to_i).each(&b)
when /\A[\s*\d+\s*(?:,\s*\d+\s*)*]\z/
eval(x).each(&b)
else
raise ArgumentError, “Don’t know what to do with: #{x}”
end
end

my_loop(“5”) {|x| p x}
0
1
2
3
4
=> 5

my_loop(“1…5”) {|x| p x}
1
2
3
4
5
=> 1…5

my_loop("[5,3,2]") {|x| p x}
5
3
2
=> [5, 3, 2]

my_loop(“1,2”) {|x| p x}
ArgumentError: Don’t know what to do with: 1,2
from (irb):10:in `my_loop’
from (irb):16
from :0

Kind regards

robert

anansi wrote:

been 1…10): but now this userinput can be a fixnum like 12 or 36 or
and I was wondering if it is possible to build this into one single
loop and not three different ones?

Assuming that userinput can only be a Range, Array, or Fixnum…both
Range and Array have an each method. Test userinput to see if it
responds to :each. If it does, you’re golden. If it doesn’t, it’s a
Fixnum. Make an array from the Fixnum by calling Array(). Now iterate
over the result using :each. (This is untested but it’ll give you an
idea of what to do.)

userinput = Array(userinput) unless userinput.respond_to? :each
userinput.each do |x|
puts x
end

P.S. the puts method converts its argument to a string. You don’t need
to use “#{x}”.

On 06.05.2007 15:30, Robert K. wrote:

The userinput is the loop count (so above the userinput would have
process numbers which can the user give in, in three different ways
(\$1.to_i … \$2.to_i).each(&b)
2

my_loop("[5,3,2]") {|x| p x}

Kind regards

``````robert
``````

more elegant:

def my_loop(x,&b)
case x
when /\A\d+\z/
1 … x.to_i
when /\A(\d+)…(\d+)\z/
(\$1.to_i … \$2.to_i)
when /\A[\s*\d+\s*(?:,\s*\d+\s*)*]\z/
eval(x)
else
raise ArgumentError, “Don’t know what to do with: #{x}”
end.each(&b)
end

more modular:

def my_enum(x,&b)
case x
when /\A\d+\z/
1 … x.to_i
when /\A(\d+)…(\d+)\z/
(\$1.to_i … \$2.to_i)
when /\A[\s*\d+\s*(?:,\s*\d+\s*)*]\z/
eval(x)
else
raise ArgumentError, “Don’t know what to do with: #{x}”
end
end

robert

Hi thank you both I took Tim’s answer because it’s faster and much smaller and my loop had
some timeout-problems with the case-when method to solve it.

Tim H. wrote:

The userinput is the loop count (so above the userinput would have
process numbers which can the user give in, in three different ways

userinput = Array(userinput) unless userinput.respond_to? :each
userinput.each do |x|
puts x
end

P.S. the puts method converts its argument to a string. You don’t need
to use “#{x}”.

greets

``````                        (
)
(
/\  .-"""-.  /\
//\\/  ,,,  \//\\
|/\| ,;;;;;, |/\|
//\\\;-"""-;///\\
//  \/   .   \/  \\
(| ,-_| \ | / |_-, |)
//`__\.-.-./__`\\
// /.-(() ())-.\ \\
(\ |)   '---'   (| /)
` (|           |) `
jgs     \)           (/
``````

one must still have chaos in oneself to be able to give birth to a
dancing star

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.