[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

fixnum, range and array into one single loop?

mrpink

5/6/2007 1:20:00 PM

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
4 Answers

Robert Klemme

5/6/2007 1:30:00 PM

0

On 06.05.2007 15:20, anansi wrote:
> 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?

How about

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

Tim Hunter

5/6/2007 1:39:00 PM

0

anansi wrote:
> 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?
>

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

--
RMagick [http://rmagick.rub...]
RMagick Installation FAQ [http://rmagick.rub.../install-faq.html]


Robert Klemme

5/6/2007 2:05:00 PM

0

On 06.05.2007 15:30, Robert Klemme wrote:
> On 06.05.2007 15:20, anansi wrote:
>> 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?
>
> How about
>
> 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

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

mrpink

5/6/2007 2:47:00 PM

0

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 Hunter wrote:
> anansi wrote:
>> 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?
>>
>
> 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}".


--
greets

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


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