38
loading...
This website collects cookies to deliver better user experience
parsing-an-encoded-string.rb
), and setting up the conditions that I wanted to test.[
# ["1h4m2s", 3842],
["1m", 60],
# ["1s2m", 121],
# ["1d", 0],
# ["10", 10],
].each do |given, expected|
# Do the magic
end
ruby parsing-an-encoded-string.rb
to see if things were working.TIME_UNIT_TO_SECONDS_MAP
hash provides a lookup for a given unit and how many seconds one of those units represents.TIME_UNIT_TO_SECONDS_MAP = {
"h" => 60 * 60, # seconds in an hour
"m" => 60, # seconds in a minute
"s" => 1 # seconds in a second
}
convert_to_seconds_via_string_splitting
method does some simple string splitting into two separate arrays and then walks those arrays together to calculate the number of seconds.def convert_to_seconds_via_string_splitting(input)
# Split on one or more numerals
#
# Because of the structure, the first element should always be an
# empty string. We may want to guard better. On the other hand,
# if the user's giving us junk, whatever.
units = input.split(/\d+/)[1..-1]
return input.to_i unless units
# Split on a single alpha character
times = input.split(/[a-z]/)
seconds = 0
units.each_with_index do |unit, i|
seconds += TIME_UNIT_TO_SECONDS_MAP.fetch(unit, 0) * times[i].to_i
end
return seconds
end
THREE_TIMES_AND_UNITS_REGEXP = /\A((\d+)([a-z]))?((\d+)([a-z]))?((\d+)([a-z]))?\Z/
convert_to_seconds_via_verbose_regexp
method handles those capture regions.THREE_TIMES_AND_UNITS_REGEXP =
/\A((\d+)([a-z]))?((\d+)([a-z]))?((\d+)([a-z]))?\Z/
def convert_to_seconds_via_verbose_regexp(input)
match = THREE_TIMES_AND_UNITS_REGEXP.match(input)
seconds = 0
return input.to_i unless match
seconds += match[2].to_i *
TIME_UNIT_TO_SECONDS_MAP.fetch(match[3], 0) if match[1]
seconds += match[5].to_i *
TIME_UNIT_TO_SECONDS_MAP.fetch(match[6], 0) if match[4]
seconds += match[8].to_i *
TIME_UNIT_TO_SECONDS_MAP.fetch(match[9], 0) if match[7]
seconds
end
TIME_AND_UNIT_REGEXP = /(\d+)([a-z])/
convert_to_seconds_via_regexp_scanner
method handles those capture regions.TIME_AND_UNIT_REGEXP = /(\d+)([a-z])/
def convert_to_seconds_via_regexp_scanner(input)
seconds = 0
matched = false
input.scan(TIME_AND_UNIT_REGEXP) do |time, unit|
matched = true
seconds += time.to_i *
TIME_UNIT_TO_SECONDS_MAP.fetch(unit, 0)
end
return seconds if matched
input.to_i
end
[
["1h4m2s", 3842],
["1m", 60],
["1s2m", 121],
["1d", 0],
["10", 10],
].each do |given, expected|
puts "Given: #{given}\tExpected: #{expected}"
[
:convert_to_seconds_via_string_splitting,
:convert_to_seconds_via_verbose_regexp,
:convert_to_seconds_via_regexp_scanner,
].each do |method|
returned_value = __send__(method, given)
if returned_value == expected
puts "\tSuccess for #{method}."
else
puts "\tFailure for #{method}. Got: #{returned_value}"
end
end
end
TIME_UNIT_TO_SECONDS_MAP
. And there are, I’m certain, many other ways to approach solving this particular thing.