简体   繁体   中英

ruby - group by repeating key of multiple hashes

I have the following array

t = [
  {nil => 1, 10 => 2, 16 => 4, 5=> 10},
  {nil => 9, 5 => 2, 17 => 3, 10 => 2},
  {10 => 4, 5 => 9, 17 => 1}
]

how can I get this as result?

{nil => [1,9,0],10 => [2,2,4], 16 => [4,0,0], 5 => [10,2,9], 17=>[0,3,1]}

I've seen that I can use something like this

t.group_by{|h| h['key']}

but I'm not sure if I can put a regexp inside the brackets

Thanks in advance

Javier

EDIT:

Is just want to group by each key of each hash inside the array, if the key is not present then the value is 0 for that hash

How about this one for illegibility:

t = [
  {nil => 1, 10 => 2, 16 => 4, 5=> 10},
  {nil => 9, 5 => 2, 17 => 3, 10 => 2},
  {10 => 4, 5 => 9, 17 => 1}
]

# Create hash of possible keys
keys = t.reduce({}) { |m, h| h.each_key { |k| m[k] = [] }; m }

# Iterate through array, for each hash, for each key, append the 
# value if key is in hash or zero otherwise
t.reduce(keys) { |m, h| m.each_key { |k| m[k] << (h[k] || 0) }; m }

puts keys
#=> {nil=>[1, 9, 0], 10=>[2, 2, 4], 16=>[4, 0, 0], 5=>[10, 2, 9], 17=>[0, 3, 1]}

I do not think there is any any function available Just gave a try with hash

  def do_my_work(data) 
    hash = {}
    #get all keys first 
    arr.map{|m| m.keys}.flatten.uniq.each {|a| hash[a]=[]}
    # Now iterate and fill the values
    arr.each do |elm|
      hash.each do |k,v|
        hash[k] << (elm[k].nil? ? 0 : elm[k])
      end
    end
  end   

  hash = do_my_work(t)

  puts hash
  # => {nil=>[1, 9, 0], 10=>[2, 2, 4], 16=>[4, 0, 0], 5=>[10, 2, 9], 17=>[0, 3, 1]} 

Not the most elegant code I've ever written, but it does the job and is easy to understand:

def jqq(a)
  keys = []
  result = {}

  a.each do |h|
    keys += h.keys
  end

  keys.uniq.each do |key|
    result[key] = []
    a.each do |h|
      h.default = 0
      result[key] << h[key]
    end
  end

  result
end

t = [
  {nil => 1, 10 => 2, 16 => 4, 5=> 10},
  {nil => 9, 5 => 2, 17 => 3, 10 => 2},
  {10 => 4, 5 => 9, 17 => 1}
]

puts jqq(t)
# {nil=>[1, 9, 0], 10=>[2, 2, 4], 16=>[4, 0, 0], 5=>[10, 2, 9], 17=>[0, 3, 1]}

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