преобразование рубиновой строки в хеш - PullRequest
2 голосов
/ 20 октября 2011

У меня есть такая строка,

str = "uu@p, xx@m, yy@n, zz@m"

Я хочу знать, как преобразовать данную строку в хеш.(т.е. мое фактическое требование состоит в том, сколько значений (перед символом @) имеют m, n и p. Я не хочу подсчета, мне нужно точное значение).Вывод будет лучше вот так:

{"m" => ["xx", "zz"], "n" => ["yy"], "p" => ["uu"]}

Может мне кто-нибудь помочь, пожалуйста?

Ответы [ 3 ]

14 голосов
/ 20 октября 2011

Прямое копирование / прошлое сеанса IRB:

>> str.split(/, /).inject(Hash.new{|h,k|h[k]=[]}) do |h, s|
..   v,k = s.split(/@/)
..   h[k] << v
..   h
..   end
=> {"p"=>["uu"], "m"=>["xx", "zz"], "n"=>["yy"]}
4 голосов
/ 20 октября 2011

Более простой код для новичка:)

str = "uu@p, xx@m, yy@n, zz@m"
h = {}
str.split(",").each do |x| 
   v,k = x.split('@')
   h[k] ||= []
   h[k].push(v)
end

p h
2 голосов
/ 20 октября 2011

Стиль FP:

grouped = str.split(", ").group_by { |s| s.split("@")[1] }
Hash[grouped.map { |d, emails| [d, emails.map { |s| s.split("@")[0] }] }]

#=> {"m"=>["xx", "zz"], "n"=>["yy"], "p"=>["uu"]}

Как обычно, решение намного короче и понятнее, если прибегнуть к Facets классным абстракциям (не нужно устанавливать всю библиотеку, просто скопируйтеспециальные методы для вашего модуля расширений):

require 'facets'
str.split(", ").map_by { |s| s.split("@", 2).reverse }
#=> {"m"=>["xx", "zz"], "n"=>["yy"], "p"=>["uu"]}

Facets#map_by = group_by + map

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...