修剪尾随.0

时间:2013-08-30 12:32:38

标签: ruby excel ruby-2.0 roo-gem

我有一个包含部件号的Excel列。这是一个样本

如您所见,它可以是许多不同的数据类型:FloatIntString。我正在使用roo gem来读取文件。问题是roo将整数单元解释为Float,向它们添加尾随零(16431 => 16431.0)。我想修剪这个尾随零。我不能使用to_i,因为它将修剪其中需要小数的单元格的所有尾随数字(上例中的第一行),并将在String行中的字符串char之后剪切所有内容(上例中的最后一行)。

目前,我有一个方法可以检查单元格的最后两个字符,如果它们是“.0”则修剪它们。

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

这很有效,但感觉非常糟糕。将Excel文件内容转换为Ruby数据结构的正确方法是什么?

4 个答案:

答案 0 :(得分: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

或者,来自字符串:

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 :(得分:19)

对于那些使用Rails的人,ActionView有一个number_with_precision方法,它采用strip_insignificant_zeros: true参数来处理这个问题。

number_with_precision(13.00, precision: 2,  strip_insignificant_zeros: true)
# => 13
number_with_precision(13.25, precision: 2,  strip_insignificant_zeros: true)
# => 13.25

http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_with_precision

答案 2 :(得分:1)

在大多数情况下,这应该涵盖您的需求:some_value.gsub(/(\.)0+$/, '')

它修剪所有尾随零和小数点,后跟零。否则,它会留下字符串。

它也非常高效,因为它完全基于字符串,不需要浮点或整数转换。 (假设您的输入值已经是字符串)

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>

答案 3 :(得分:-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