2013-08-30 7 views
11

Ich habe eine Excel-Spalte mit Teilenummern. Hier ist ein BeispielTrimmen ein nachlaufendes .0

Wie Sie sehen können, kann es viele verschiedene Datentypen sein: Float, Int und String. Ich verwende roo Edelstein, um die Datei zu lesen. Das Problem ist, dass roo Ganzzahlzellen als Float interpretiert und ihnen eine abschließende Null hinzufügt (16431 => 16431.0). Ich möchte diese nacheilende Null trimmen. Ich kann to_i nicht verwenden, weil es alle nachkommenden Zahlen der Zellen trimmt, die eine Dezimalzahl in ihnen erfordern (die erste Zeile im obigen Beispiel) und alles nach einer Zeichenfolge in den Zeilen String schneidet (die letzte Zeile im obigen Beispiel)).

Derzeit habe ich eine eine Methode, die die letzten beiden Zeichen der Zelle überprüft und trimmt sie, wenn sie“0,0"

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

Dies funktioniert, aber es fühlt sich schrecklich und Hacky. Was ist der richtige Weg, um den Inhalt meiner Excel-Datei in eine Ruby-Datenstruktur zu bringen?

Antwort

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 

oder aus string:

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

oder nur result = result.to_i if result == result.to_i – peter

0

Versuchen:

"16431.0".to_i 
#=> 16431 
+1

Ich kann 'to_i' nicht verwenden, weil ich die Float-Eigenschaften von Zellen beibehalten muss, die tatsächlich eine Dezimalzahl in ihnen haben. Frage aktualisiert –

+0

@DanGarman Ich verstehe, dass diese Antwort nicht Ihre Bedürfnisse erfüllt, aber Ihre "trim" nicht so gut. Es gibt 'nil' zurück, wenn der Gleitkommawert nicht in eine Ganzzahl umgewandelt werden soll. – sawa

+0

Warum unten abstimmen? Meine Antwort war nicht falsch, die Frage erwähnte diese Anforderung nicht ... –

-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

Das ist das Gleiche wie der erste Teil meiner Antwort, nur dass Sie keine Memoization machen. – sawa

+0

korrekt. Ich habe es nicht gesehen, als ich angefangen habe zu schreiben. Hat es jetzt bearbeitet. – jomo

+0

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

0

dies Ihre Bedürfnisse in den meisten Fällen abdecken sollte: some_value.gsub(/(\.)0+$/, '')

Es trimmt alle Nullen und ein Komma gefolgt nur von Nullen Hinter. Andernfalls wird die Zeichenfolge allein gelassen.

Es ist auch sehr performant, da es vollständig String-basiert ist, keine Fließkomma- oder Integer-Konvertierungen benötigt. (Angenommen, Ihr Eingabewert ist bereits eine Zeichenfolge)

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>