简体   繁体   中英

How to convert a Hash with values as arrays to a Hash with keys from array and values as array of keys?

I have a hash of the following form:

{ 1 => [], 2 => ["A", "B"], 3 => ["C"], 4 => ["B", "C"], 5 => ["D"] }

what's the best way to transform this in Ruby to:

{ "A" => [2], "B" => [2, 4], "C" => [3, 4], "D" => [5], "default" => [1] }

The best way I know.

hash = { 1 => [], 2 => ['A','B'], 3 => ['C'], 4 => ['B','C'], 5 => ['D'] }

new_hash = hash.inject({}) do |result, (key, values)|
  values.each do |value|
    result[value] ||= []
    result[value].push(key)
  end
  result[:default] = [key] if values.empty?

  result
end

puts new_hash

A bit of more functional approach:

array
  .flat_map {|k,v| v.product([k])}
  .group_by(&:first)
  .transform_values {|v| v.map(&:last) }
input = { 1 => [], 2 => ['A', 'B'], 3 => ['C'], 4 => ['B', 'C'], 5 => ['D'], 6 => [] }
output =
  input.each_with_object(Hash.new([])) do |(key, values), hash|
    values.each { |value| hash[value] += [key] }
    hash['default'] += [key] if values.empty?
  end

output
# => {"default"=>[1, 6], "A"=>[2], "B"=>[2, 4], "C"=>[3, 4], "D"=>[5]}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM