Ruby разбивает String на две секции и помещает в хеш с предопределенными ключами - PullRequest
7 голосов
/ 12 июля 2011

Я не знаю, действительно ли это хороший код ruby, но я пытаюсь разбить строку на две отдельные секции и поместить их в качестве значений для двух конкретных ключей. Например:

  name_a = "Henry Fillenger".split(/\s+/,2)
  name = {:first_name => name_a[0], :last_name => name_a[1]}

Мне было интересно, можно ли это сделать одной строкой с помощью какой-нибудь рубиновой магии.

Ответы [ 3 ]

19 голосов
/ 12 июля 2011

Вы можете использовать Hash[] и zip, чтобы сделать это:

name = Hash[ [:first_name, :last_name].zip("Henry Fillenger".split(/\s+/,2)) ]

Однако я бы сказал, что ваша версия более читабельна.Не все должно быть в одной строке.

7 голосов
/ 12 июля 2011

Еще две строки, но, на мой взгляд, чуть более читабельные,

first_name, last_name = "Henry Fillenger".split(/\s+/,2)
name = {:first_name => first_name, :last_name => last_name}
2 голосов
/ 12 июля 2011

Просто для удовольствия, неразделенный вариант (который также состоит из двух строк):

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] }

Интересными частями будут именованные группы захвата ((?<first_name>...)) в регулярном выражении и общая техника хеширования с использованием each_with_object. Для именованных групп захвата требуется 1,9.

Если бы кто-нибудь осмелился, можно было бы обезьяна вставить патч each_with_object прямо в MatchData как, скажем, to_hash:

class MatchData
    def to_hash
        names.each_with_object({ }) { |name, h| h[name.to_sym] = self[name] }
    end
end

И тогда вы можете получить свою однострочную строку:

name = "Henry Fillenger".match(/(?<first_name>\S+)\s+(?<last_name>\S+)/).to_hash

Я не очень рекомендую это, я только поднимаю это как предмет интереса. Я немного разочарован тем, что MatchData уже не имеет метода to_h или to_hash, он станет разумным дополнением к его to_a методу.

...