问题描述:

I have a hash like below:

{

'3.2':{

'abc-4536':{

"a" : "sfsdfs",

"b" : "qweqda",

"pa": "Printer"

},

'abc-2345':{

"a": "sdfswer",

"b": "werwewe",

"pa": "NewsPaper"

},

'abc-4536':{

"a" : "sfsdfs",

"b" : "qweqda",

"pa": "Printer"

},

...

}

}

So, now i have to arrange it like this:

{

'3.2':{

"Printer":{

'count': 2

},

"NewsPaper":{

'count': 3

},

}

}

i have to count and group by "pa" key inside '3.2'. Any ideas ?

网友答案:

Assuming that you have an array of specified objects:

array.map{ |x| { x.first[0] => x.first[1].map { |k,v| [v['pa'], "calculated value"] }.to_h } }

or if you have one hash:

{ hash.first[0] => hash.first[1].map { |k,v| [v['pa'], "calculated value"] }.to_h } 
网友答案:

Using the below as your example hash (2 counts of "Printer" and 1 count of "NewsPaper"):

h = {:"3.2"=>{:"abc-4536"=>{:a=>"sfsdfs", :b=>"qweqda", :pa=>"Printer"}, :"abc-2345"=>{:a=>"sdfswer", :b=>"werwewe", :pa=>"NewsPaper"}, :"abc-4537"=>{:a=>"sfsdfs", :b=>"qweqda", :pa=>"Printer"}}}

You can do:

z = Array.new
h[:"3.2"].each_value {|x| z << x[:pa]}
h[:"3.2"] = Hash.new
z.each {|a| h[:"3.2"][a] = {"count": z.count {|x| x == a}}}

h is now:

#=> {:"3.2"=>{"Printer"=>{:count=>2}, "NewsPaper"=>{:count=>1}}}
网友答案:

Let's say you dump the hash we're really working with into a variable just for the sake of demonstrating. I'm going to refer to the hash you wrote out above as "old_hash".

REVISED

Reflects your needs for a "count" now.

    # Isolate the part with which we're working. If you had multiple
    #   version (like 3.1, 3.0) just perform this on .each of them.
    x = old_hash['3.2']

    # Initialize a counter
    counter = 0

    # Iterate through every level in '3.2'
    x.each do |k, v|

      # Increment the counter
      counter += 1

      # Create a new key-value pair in x, where the key is the "pa"
      #   value of hash currently selected by this loop, and assign
      #   it a count
      x[ x[k]['pa'] ] = { count: counter }

      # Remove the hash currently selected by your loop from x
      #  (if you're using its other values for a calulation, make
      #   sure you do that first)
      x.delete( k )
    end

    # Rewrite your old "3.2" into the new hash
    old_hash['3.2'] = x

There are much more elegant ways of doing this, but this should at least be an easy-to-understand process, and if you have complicated calculations to perform, now you have a lot of space for readability.

相关阅读:
Top