2013-08-30 17 views
11

Mam kolumnę Excel zawierającą numery części. Oto próbkaPrzycinanie końcowe .0

Jak widać, może być wiele różnych typów danych: Float, Int i String. Używam klejnotu roo do odczytu pliku. Problem polega na tym, że roo interpretuje komórki całkowite jako Float, dodając do nich końcowe zero (16431 => 16431.0). Chcę przyciąć to końcowe zero. Nie mogę użyć to_i, ponieważ przycinam wszystkie końcowe numery komórek, które wymagają ułamka dziesiętnego (pierwszy wiersz w powyższym przykładzie) i wycina wszystko po znaku ciąg w wierszach String (ostatni wiersz w powyższym przykładzie).

Obecnie mam metodę, która sprawdza dwa ostatnie znaki komórki i trymuje ich, czy są one”0,0"

def trim(row) 
    if row[0].to_s[-2..-1] == ".0" 
     row[0] = row[0].to_s[0..-3] 
    end 
end 

To działa, ale czuje straszny i hacky. Jaki jest właściwy sposób uzyskania zawartości pliku Excel w strukturze danych w języku Ruby?

Odpowiedz

40
def trim num 
    i, f = num.to_i, num.to_f 
    i == f ? i : f 
end 

trim(2.5) # => 2.5 
trim(23) # => 23 

lub z wyrażenie:

def convert x 
    Float(x) 
    i, f = x.to_i, x.to_f 
    i == f ? i : f 
rescue ArgumentError 
    x 
end 

convert("fjf") # => "fjf" 
convert("2.5") # => 2.5 
convert("23") # => 23 
convert("2.0") # => 2 
convert("1.00") # => 1 
convert("1.10") # => 1.1 
+1

lub po prostu result = result.to_i if result == result.to_i – peter

0

Spróbuj:

"16431.0".to_i 
#=> 16431 
+1

Nie mogę użyć 'to_i', ponieważ muszę utrzymywać właściwości zmiennoprzecinkowe komórek, które faktycznie mają w nich wartość dziesiętną. Pytanie zaktualizowane. –

+0

@DanGarman Rozumiem, że ta odpowiedź nie spełnia Twoich potrzeb, ale twoje "wykończenie" nie jest tak dobre. Zwraca 'nil', gdy float nie powinien być konwertowany na liczbę całkowitą. – sawa

+0

Dlaczego w dół głosowanie? Moja odpowiedź nie była zła, pytanie nie wspominało o tym wymogu ... –

-1

Numeric values are returned as type :float

def convert_cell(cell) 
    if cell.is_a?(Float) 
    i = cell.to_i 
    cell == i.to_f ? i : cell 
    else 
    cell 
    end 
end 

convert_cell("foobar") # => "foobar" 
convert_cell(123) # => 123 
convert_cell(123.4) # => 123.4 
+0

To jest to samo, co pierwsza część mojej odpowiedzi, z wyjątkiem tego, że nie robisz memoizacji. – sawa

+0

prawidłowe. nie widziałem tego, kiedy zacząłem pisać. Zmieniono to teraz. – jomo

+0

'convert_string (" 1.00 ") # =>" 1.00 "', 'convert_string (" 1.20 ") # =>" 1.20 "' – sawa

0

To powinno pokryć swoje potrzeby w większości przypadków: some_value.gsub(/(\.)0+$/, '')

To przycina wszystkie zera końcowe i punkt dziesiętny następuje tylko zer. W przeciwnym razie pozostawia łańcuch w spokoju.

Jest również bardzo wydajny, ponieważ jest całkowicie oparty na ciągach, nie wymaga konwersji zmiennoprzecinkowej ani całkowitej. (Zakładając, że twoja wartość wejściowa jest już ciągiem znaków):

Loading development environment (Rails 3.2.19) 
irb(main):001:0> '123.0'.gsub(/(\.)0+$/, '') 
=> "123" 
irb(main):002:0> '123.000'.gsub(/(\.)0+$/, '') 
=> "123" 
irb(main):003:0> '123.560'.gsub(/(\.)0+$/, '') 
=> "123.560" 
irb(main):004:0> '123.'.gsub(/(\.)0+$/, '') 
=> "123." 
irb(main):005:0> '123'.gsub(/(\.)0+$/, '') 
=> "123" 
irb(main):006:0> '100'.gsub(/(\.)0+$/, '') 
=> "100" 
irb(main):007:0> '127.0.0.1'.gsub(/(\.)0+$/, '') 
=> "127.0.0.1" 
irb(main):008:0> '123xzy45'.gsub(/(\.)0+$/, '') 
=> "123xzy45" 
irb(main):009:0> '123xzy45.0'.gsub(/(\.)0+$/, '') 
=> "123xzy45" 
irb(main):010:0> 'Bobby McGee'.gsub(/(\.)0+$/, '') 
=> "Bobby McGee" 
irb(main):011:0>