Стиль 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