From: Robert Klemme Date: 2007-03-16T06:55:05+09:00 Subject: Re: Need help converting Perl to Ruby (detecting integers and decimals in strings) On 15.03.2007 22:39, Paul wrote: > I am trying to convert a Perl script to Ruby and have been having some > difficulty along the way (mostly because I don't know Perl). > > I am currently stumped on one particular line in the old Perl script: > --- > foreach (@rawfields) {if ($_ > 0){$_ = int($_*100)/100}} > --- > > Background context: @rawfields is an array that holds the contents of > an imported line from a text file. Here are some sample lines from > the input file: > --- > "0" "0" "0" "0" "0" "0" "Bar" > "5.66666" "0" "3.566662" "1.383332" "6" "0" "Foo" > --- > > My guess is that the Perl line iterates through each of the elements > in the array and rounds any integers to 2 decimals. > > This raises a few problems for me. > > 1) How can I easily tell if the (string) value in each array element > is an integer or has a decimal value? > > => The desired output for text file line 2 is : > --- > "5.67" "0" "3.57" "1.38" "6" "0" "Foo" > --- > > > I tried the following in Ruby: > --- > @rawfields.each_index do |x| > if ( @rawfields[x].to_f > 0 ) > @rawfields[x] = ( (( @rawfields[x].to_f * 100 ).round.to_i ).to_f / > 100 ).to_s > end > end > --- > > But it produces the following output: > --- > "5.67" "0" "3.57" "1.38" "6.0" "0" "Foo" > --- > > ...which is close, but not quite what I want. My output file now has > values like 1.0, 5.0, 62.0, etc. If it's an integer, I don't want to > see the decimal. > > Can anyone suggest an improvement to my code or a better translation > from Perl? > > TIA. Paul. > How about irb(main):005:0> fields = %w{5.6666 0 Foo} => ["5.6666", "0", "Foo"] irb(main):006:0> fields.map {|v| sprintf("%4.2f", Float(v)) rescue v} => ["5.67", "0.00", "Foo"] This uses the fact that Float() will throw if the string is not a valid number. If you really need "0" instead of "0.00" you could apply another test. If you need the quotes you could do irb(main):008:0> puts fields.map {|v| (sprintf("%4.2f", Float(v)) rescue v).inspect}.join(" ") "5.67" "0.00" "Foo" Kind regards robert