Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby split String into two sections and put in hash with predefined keys

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.

like image 234
Craig Avatar asked Jul 12 '11 01:07

Craig


People also ask

How do you split a string in Ruby?

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.

How do you split a string into an array in Ruby?

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.

How do you add something to a Hash in Ruby?

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.


3 Answers

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.

like image 193
sepp2k Avatar answered Oct 04 '22 21:10

sepp2k


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}
like image 30
Ray Baxter Avatar answered Oct 04 '22 22:10

Ray Baxter


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.

like image 29
mu is too short Avatar answered Oct 04 '22 21:10

mu is too short