Q:

How to get specific attributes from array from hash? 

I have an array of hash that needs to be sorted by imp and I want to get the specific attribute out of it. 
array_of_hash is 
[
  {
      :id => "9",
      :subsystem => "xyz",
      :component => "xyz",
      :imp => "1",
      :old_serial => "55q",
      :current_serial => nil,
      :old_num => "same",
      :current_num => nil,
      :acceptable_nums => [
         "asdf",
         "qwer",
         "zxcv",
         "poiu"
    ]
},
 {
     :id => "10",
     :subsystem => "xyz",
     :component => "xyz",
     :imp => "4",
     :old_serial => "56t",
     :current_serial => nil,
     :old_num => "same",
     :current_num => nil,
     :acceptable_nums => [
         "asdf",
         "qwer",
         "zxcv",
         "poiu"
    ]
},
{
      :id => "11",
      :subsystem => "xyz",
      :component => "xyz",
      :imp => "3",
      :old_serial => "57s",
      :current_serial => nil,
      :old_num => "same",
      :current_num => nil,
      :acceptable_nums => [
        "asdf",
        "qwer",
        "zxcv",
        "poiu"
    ]
},
  {
     :id => "14",
     :subsystem => "xyz",
     :component => "xyz",
     :imp => "2",
     :old_serial => "58r",
     :current_serial => nil,
     :old_num => "same",
     :current_num => nil,
     :acceptable_nums => [
        "asdf",
        "qwer",
        "zxcv",
        "poiu"
    ]
}
]

First step, sorting
array_of_hash.sort_by {|hash| hash[:imp].to_i}

Then i want specific attribute
Desired output with some condition
{
      :imp => "1-4",  #It should be range
      :old_serial => "55q,56r,57s,58t",  #old_serial number should be separated with comma respectively 
      :old_num => "same",
      :acceptable_nums => [
         "asdf",
         "qwer",
         "zxcv",
         "poiu"
    ]
}

I am not able to figure out how to do this. 

A:

You'll need a combination of sort_by, group_by and map :
p array_of_hash.sort_by { |h| h[:imp] }
               .group_by{ |h| h.values_at(:acceptable_nums, :old_num) }
               .map{ |(old_num, nums), hashes|
  {
    imp: hashes.map{ |h| h[:imp].to_i },
    old_serial: hashes.map{ |h| h[:old_serial] }.join(','),
    old_num: old_num,
    acceptable_nums: nums
  }
}
# [{:imp=>[1, 2, 3, 4], :old_serial=>"55q,58r,57s,56t", :old_num=>["asdf", "qwer", "zxcv", "poiu"], :acceptable_nums=>"same"}]

The output is an array of hashes.  There will be one hash for each unique pair of old_num and acceptable_nums.  In your example, all the hashes had this same pair, so only one hash is outputted. 
As for the desired conversion from [1,2,3,4] to "1-4", the documentation for slice_when does just that :
a = [1,2,4,9,10,11,12,15,16,19,20,21]
b = a.slice_when {|i, j| i+1 ! = j }
p b.to_a #=> [[1, 2], [4], [9, 10, 11, 12], [15, 16], [19, 20, 21]]
c = b.map {|a| a.length < 3 ?  a : "#{a.first}-#{a.last}" }
p c #=> [[1, 2], [4], "9-12", [15, 16], "19-21"]
d = c.join(",")
p d #=> "1,2,4,9-12,15,16,19-21"

