I would like to extract some information from a string in Ruby by only reading the String once (O(n) time complexity).
Here is an example:
The string looks like this: -location here -time 7:30pm -activity biking
I have a Ruby object I want to populate with this info. All the keywords are known, and they are all optional.
def ActivityInfo
_attr_reader_ :location, :time, :activity
def initialize(str)
@location, @time, @activity = DEFAULT_LOCATION, DEFAULT_TIME, DEFAULT_ACTIVITY
# Here is how I was planning on implementing this
current_string = ""
next_parameter = nil # A reference to keep track of which parameter the current string is refering to
words = str.split
while !str.empty?
word = str.shift
case word
when "-location"
if !next_parameter.nil?
next_parameter.parameter = current_string # Set the parameter value to the current_string
current_string = ""
else
next_parameter = @location
when "-time"
if !next_parameter.nil?
next_parameter.parameter = current_string
current_string = ""
else
next_parameter = @time
when "-activity"
if !next_parameter.nil?
next_parameter.parameter = current_string
current_string = ""
else
next_parameter = @time
else
if !current_string.empty?
current_string += " "
end
current_string += word
end
end
end
end
So basically I just don’t know how to make a variable be the reference of another variable or method, so that I can then set it to a specific value. Or maybe there is just another more efficient way to achieve this?
Thanks!
The string looks suspiciously like a command-line, and there are some good Ruby modules to parse those, such as
optparse.Assuming it’s not, here’s a quick way to parse the commands in your sample into a hash:
Which results in:
Expanding it a bit farther:
Which sets
actto an instance of ActivityInfo looking like:—
The OP asked how to deal with situations where the commands are not flagged with
-or are multiple words. These are equivalent, but I prefer the first stylistically:If the commands are multiple words, such as “at location”:
If you need even more flexibility look at Ruby’s
strscanmodule. You can use that to tear apart a string and find the commands and their parameters.