I don't know if this is actually good ruby code, but what I am trying to do is split a String into two separ开发者_StackOverflowate 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.
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.
精彩评论