Created
January 26, 2016 18:55
-
-
Save dmitryzuev/7d842cddc3127c5941af to your computer and use it in GitHub Desktop.
Convert human readable number to float in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Convert human entered string into number | |
class StringDecoder | |
# Hash with powers of 10 by names | |
POWERS = { | |
'trillion' => 10**12, | |
'trillions' => 10**12, | |
'billion' => 10**9, | |
'billions' => 10**9, | |
'million' => 10**6, | |
'millions' => 10**6, | |
'thousand' => 10**3, | |
'thousands' => 10**3, | |
}.freeze | |
# Only one public method for service object: #call | |
def call(input) | |
# Return if input is numeric (and don't forget to strip spaces and commas) | |
return input.gsub(/[\s,]/, '').to_f if float? input.gsub(/[\s,]/, '') | |
result = 0 | |
# First line: insert spacebar if there is no one between integer and word | |
# Second line: split array by space | |
# Third line: convert each word to its numeric format | |
# Fourth line: slice array by 2 elements | |
# Fifth line: multiply each chunk and sum everything | |
input.gsub(/(?<=[\d])(?=[а-яА-Я])/, ' ') | |
.split(' ') | |
.map { |i| POWERS[i] ? POWERS[i].to_f : i.to_f } | |
.each_slice(2) do |slice| | |
result += slice.inject(:*) | |
end | |
result | |
end | |
private | |
# Check if given string may be converted to float | |
def float?(input) | |
input[/\A[\d]+[\.]?[\d]*\z/] == input | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment