1

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 ?

Sid
  • 2,683
  • 18
  • 22
Ahmad hamza
  • 1,816
  • 1
  • 23
  • 46

3 Answers3

0

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 } 
lx00st
  • 1,566
  • 9
  • 17
0

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}}}
Sid
  • 2,683
  • 18
  • 22
-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.

ConnorCMcKee
  • 1,625
  • 1
  • 11
  • 23