Parse abbreviated numbers in Ruby
What's the best way in Ruby to turn human-readable abbreviated numbers into actual i开发者_如何学Gontegers?
Examples:
"1.2M" => 1200000
"477k" => 477000
module SIValue
# http://en.wikipedia.org/wiki/SI_prefix
PREFIX_MAGNITUDES = {
'Y' => 24, 'Z' => 21, 'E' => 18, 'P' => 15, 'T' => 12,
'G' => 9, 'M' => 6, 'k' => 3, 'h' => 2, 'da' => 1,
'd' => -1, 'c' => -2, 'm' => -3, 'μ' => -6, 'n' => -9,
'p' => -12, 'f' => -15, 'a' => -18, 'z' => -21, 'y' => -24
}
def self.from( str )
_, num, prefix = str.match(/^([-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)(#{PREFIX_MAGNITUDES.keys.join('|')})?/o).to_a
if num
prefix ? num.to_f * 10**PREFIX_MAGNITUDES[prefix] : num.to_f
else
0.0
end
end
end
%w[ 1k +3.3m +3.3M 123.123da 0.31h 0.31μ cats ].each do |s|
p [s,SIValue.from(s) ]
end
#=> ["1k", 1000.0]
#=> ["+3.3m", 0.0033]
#=> ["+3.3M", 3300000.0]
#=> ["123.123da", 1231.23]
#=> ["0.31h", 31.0]
#=> ["0.31μ", 3.1e-07]
#=> ["cats", 0.0]
def scale s
a = s.downcase.split /(?=[a-z])/
Integer(a.first.to_f * Hash.new(1).merge('k' => 1024, 'm' => 1024 * 1024)[a[1]] + 0.5)
end
# you may want to extend the hash with more suffix types
精彩评论