如何将CSV中的3.2K和5.6M值转换为Ruby中的整数并添加它们

时间:2016-08-26 22:36:00

标签: ruby csv syntax spreadsheet data-analysis

如何将1.23M和7.89K值转换为常规整数并在:damage_property:damage_crops中添加所有值?

在伪代码中它将是:

  • 使用“K”标识值,从字符串末尾删除“K”,将字符串转换为float,乘以1000
  • 用“M”标识值,从字符串末尾删除“M”,将字符串转换为float,乘以1000000
  • 忽略空白值,包括所有其他值
  • 将类别:damage_property:damage_crops
  • 中的所有值相加

我写了一些代码,但它不起作用:

kdata_property = states.select do |element| 
  element[:damage_property]
   if element.includes?"K"
     remove "K"
     element.to_f
     element*1000
   end
  end

然后我们的想法是做kdata_crops,mdata_property,mdata_crops,plaindata,并将其全部添加。有人可以帮忙吗?我想我在.includes做错了。

2 个答案:

答案 0 :(得分:1)

请尝试以下代码。我将states.select更改为states.map。我想这就是你想要的。

kdata_property = states.map do |element|
  # This line will remove leading and trailing whitespace characters
  value = element[:damage_property].nil? ? "" : element[:damage_property].strip

  # Check if last character is k or K
  if value[-1] == "K" || value[-1] == "k"
    # Take substring without last character
    value[0..-2].to_f * 1000
  elsif value[-1] == "M" || value[-1] == "m"
    value[0..-2].to_f * 1000000
  else
    nil
  end
end

# This will sum all values
kdata_property.compact.inject(0) { |sum, value| sum + value }

答案 1 :(得分:0)

我从以下内容开始:

[
  ' 12345.67890 ',
  '3.14159',
  '7.89K',
  '1.23M',
  '3.141B',
].map{ |v|
  multiplier = case v.strip[/.$/].upcase
              when 'K'
                1_000
              when 'M'
                1_000_000
              when 'B'
                1_000_000_000
              else
                1
              end
  v.to_f * multiplier
}
# => [12345.6789, 3.14159, 7890.0, 1230000.0, 3141000000.0]

这处理" K"," M"和" B",加上没有指定时,加上是否有前导和/或尾随空格。

这是有效的,因为v.to_f忽略了乘数的非数字字符:

'3.14159'.to_f # => 3.14159
'7.89K'.to_f # => 7.89

剩下的问题留待你解决。