如何将 CSV 中的 3.2K 和 5.6M 值转换为 Ruby 中的整数并相加
How to convert 3.2K and 5.6M values in CSV to integers in Ruby and add them
如何将 1.23M 和 7.89K 值转换为常规整数并将 :damage_property
和 :damage_crops
中的所有值相加?
在伪代码中它将是:
- 用 "K" 识别值,从字符串末尾删除 "K",将字符串转换为浮点数,乘以 1000
- 用 "M" 识别值,从字符串末尾删除 "M",将字符串转换为浮点数,乘以 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
.
上做错了什么
试试下面的代码。我将 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 }
我将从以下内容开始:
[
' 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",加上没有指定的时候,加上是否有前导and/or尾随空格。
之所以可行,是因为 v.to_f
忽略了乘数的非数字字符:
'3.14159'.to_f # => 3.14159
'7.89K'.to_f # => 7.89
剩下的问题留给你自己去想。
如何将 1.23M 和 7.89K 值转换为常规整数并将 :damage_property
和 :damage_crops
中的所有值相加?
在伪代码中它将是:
- 用 "K" 识别值,从字符串末尾删除 "K",将字符串转换为浮点数,乘以 1000
- 用 "M" 识别值,从字符串末尾删除 "M",将字符串转换为浮点数,乘以 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
.
试试下面的代码。我将 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 }
我将从以下内容开始:
[
' 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",加上没有指定的时候,加上是否有前导and/or尾随空格。
之所以可行,是因为 v.to_f
忽略了乘数的非数字字符:
'3.14159'.to_f # => 3.14159
'7.89K'.to_f # => 7.89
剩下的问题留给你自己去想。