Ruby объединяет хэши, помещая ключи в строку csv - PullRequest
3 голосов
/ 24 марта 2011

Есть ли умный способ добиться следующего в Ruby?

hash1 = { "a" => 1, "b" => 2, "d" => 3}
hash2 = { "a" => 4, "b" => 5, "c" => 7}
hash3 = { "a" => 4, "d" => 7, "e" => 9}
puts hash1.csvMerge(hash2).csvMerge(hash3)

с выводом:

{ "a" => "1,4,4",
  "b" => "2,5,0",
  "c" => "0,7,0",
  "d" => "3,0,7",
  "e" => "0,0,9" }

Что я пытаюсь сделать, это объединить кучуХэши Ruby, на практике у меня их более десятка, в один хеш, где значения объединяются в строку через запятую.

Ответы [ 5 ]

2 голосов
/ 24 марта 2011
hash1.merge(hash2){|key, oldval, newval| [oldval,newval].join(",")}
 => {"a"=>"1,4", "b"=>"2,5", "d"=>3, "c"=>7} 
1 голос
/ 12 января 2012

Функциональный подход:

hashes = [hash1, hash2, hash3]
result = Hash[hashes.flat_map(&:keys).uniq.map do |key|
  [key, hashes.map { |h| h[key] || 0 }.join(",")]
end]
#=> {"a"=>"1,4,4", "b"=>"2,5,0", "c"=>"0,7,0", "d"=>"3,0,7", "e"=>"0,0,9"}
1 голос
/ 24 марта 2011
hash1 = { "a" => 1, "b" => 2, "d" => 3}
hash2 = { "a" => 4, "b" => 5, "c" => 7}
hash3 = { "a" => 4, "d" => 7, "e" => 9}

hashes = [hash1, hash2, hash3]
hashes.each{|h| h.each{|k,v| h[k] = v.to_s }}
res = hashes.inject{|m,h| m.merge(h){|k,old,new| "#{old},#{new}" }} #merge and glue

p res
#=> {"a"=>"1,4,4", "b"=>"2,5", "d"=>"3,7", "c"=>"7", "e"=>"9"}
1 голос
/ 24 марта 2011

Я не знаю, есть ли у нее проблемы с производительностью

hashes = [hash1, hash2, hash3]
hash_with_all_keys = {}
hashes.each{|hash| hash_with_all_keys.merge!(hash)}
keys = hash_with_all_keys.keys
result_hash_mapping = keys.map do |key|
  value = hashes.map{|hash| hash[key].to_i}.join(",")
  [key, value]
end
result_hash = Hash[result_hash_mapping]

Я мог бы заменить строки 2-4 на keys = hashes.inject({}){|merge_hash, hash| merge_hash.merge(hash)}.keys, но мне трудно читать.

1 голос
/ 24 марта 2011
hashes = [hash1, hash2, hash3]
keys = hashes.inject({}){|hh, h| hh = hh.merge(h); hh}.keys   # the set of all keys #
default_hash = keys.inject({}){|d, k| d[k] = 0; d}    # hash with value 0 for all keys #
complemented_hashes = hashes.map{|h| default_hash.merge(h)} # missing values filled in #

p Hash[complemented_hashes.map{|h| h.to_a}.flatten(1).group_by{|k, v| k}.
map{|k, v| [k, v.map{|k, v| v}.join(",")]}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...