I don't know if this is actually good ruby code, but what I am trying to do is split a String into two separate sections and put the two as values to two specific keys. For example:
name_a = "Henry Fillenger".split(/\s+/,2)
name = {:first_name => name_a[0], :last_name => name_a[1]}
I was wondering if this could be done in a single line through some ruby magic however.
split is a String class method in Ruby which is used to split the given string into an array of substrings based on a pattern specified. Here the pattern can be a Regular Expression or a string. If pattern is a Regular Expression or a string, str is divided where the pattern matches.
The general syntax for using the split method is string. split() . The place at which to split the string is specified as an argument to the method. The split substrings will be returned together in an array.
Hash literals use the curly braces instead of square brackets and the key value pairs are joined by =>. For example, a hash with a single key/value pair of Bob/84 would look like this: { "Bob" => 84 }. Additional key/value pairs can be added to the hash literal by separating them with commas.
You can use Hash[]
and zip
to do this:
name = Hash[ [:first_name, :last_name].zip("Henry Fillenger".split(/\s+/,2)) ]
However I'd say your version is more readable. Not everything has to be on one line.
Still two lines, but slightly more readable in my opinion,
first_name, last_name = "Henry Fillenger".split(/\s+/,2)
name = {:first_name => first_name, :last_name => last_name}
Just for fun, a non-split variant (which is also two lines):
m = "Henry Fillenger".match(/(?<first_name>\S+)\s+(?<last_name>\S+)/)
name = m.names.each_with_object({ }) { |name, h| h[name.to_sym] = m[name] }
The interesting parts would be the named capture groups ((?<first_name>...)
) in the regex and the general hash-ification technique using each_with_object
. The named capture groups require 1.9 though.
If one were daring, one could monkey patch the each_with_object
bit right into MatchData
as, say, to_hash
:
class MatchData
def to_hash
names.each_with_object({ }) { |name, h| h[name.to_sym] = self[name] }
end
end
And then you could have your one-liner:
name = "Henry Fillenger".match(/(?<first_name>\S+)\s+(?<last_name>\S+)/).to_hash
I don't really recommend this, I only bring it up as a point of interest. I'm a little disappointed that MatchData
doesn't have a to_h
or to_hash
method already, it would make a sensible complement to its to_a
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With