How to sort this nested hash

s = {‘s1’=>{‘hn1’=>{‘15’=> {‘m1’=> [‘aa’, ‘bb’] }}}, ‘s3’=>{‘hn2’=>{‘10’
=> {‘m2’ => [‘cc’] }}}, ‘s2’=>{‘hn3’=>{‘50’=> {‘m3’ => [‘dd’] }}}}

How to sort the above nested hash by keys like ‘15’, ‘10’, ‘50’ shown
above?

The result should look like:

{‘s2’=>{‘hn3’=>{‘50’=> {‘m3’ => [‘dd’]}}}, ‘s1’=>{‘hn1’=>{‘15’=> {‘m1’=>
[‘aa’, ‘bb’] }}}, ‘s3’=>{‘hn2’=>{‘10’ => {‘m2’ => [‘cc’] }}}}

On Mon, Jul 2, 2012 at 9:21 AM, yibin z. [email protected] wrote:

s = {‘s1’=>{‘hn1’=>{‘15’=> {‘m1’=> [‘aa’, ‘bb’] }}}, ‘s3’=>{‘hn2’=>{‘10’
=> {‘m2’ => [‘cc’] }}}, ‘s2’=>{‘hn3’=>{‘50’=> {‘m3’ => [‘dd’] }}}}

How to sort the above nested hash by keys like ‘15’, ‘10’, ‘50’ shown
above?

The result should look like:

{‘s2’=>{‘hn3’=>{‘50’=> {‘m3’ => [‘dd’]}}}, ‘s1’=>{‘hn1’=>{‘15’=> {‘m1’=>
[‘aa’, ‘bb’] }}}, ‘s3’=>{‘hn2’=>{‘10’ => {‘m2’ => [‘cc’] }}}}

First of all, a Hash is not sorted, so the result cannot be what you
typed. You can sort a Hash and store the result in somethins that is
sorted, like an array. Next, you can use the method sort_by, which
sorts an Enumerable object by the computation of the block you pass to
it. Your structure is a bit complex, too much nesting there, but
something like this could work:

1.9.2p290 :007 > s.sort_by{|k,v| tmp = v[v.keys.first]; -
(tmp.keys.first).to_i}
=> [[“s2”, {“hn3”=>{“50”=>{“m3”=>[“dd”]}}}], [“s1”,
{“hn1”=>{“15”=>{“m1”=>[“aa”, “bb”]}}}], [“s3”,
{“hn2”=>{“10”=>{“m2”=>[“cc”]}}}]]

Jesus.

On Jul 2, 2012, at 00:52 , Jess Gabriel y Galn wrote:

First of all, a Hash is not sorted, so the result cannot be what you
typed. You can sort a Hash and store the result in somethins that is
sorted, like an array.

nit: s/sorted/ordered/g

Hi,

Like Jesus already said, you cannot sort a Hash. But of course you can
build a new Hash based on the sorted keys. A Hash actually is ordered
by the order of which you inserted the values (I think this was
introduced in Ruby 1.9).

Apart from that I agree with Jesus that the structure is much too
complex. It’s almost unreadable, a pain to process and very error-prone
(you rely on a certain structure which isn’t enforced at all). You
should definitely switch to an object structure with meaningful
entities.

On Mon, Jul 2, 2012 at 2:24 PM, Jan E. [email protected] wrote:

Like Jesus already said, you cannot sort a Hash. But of course you can
build a new Hash based on the sorted key. A Hash actually is ordered
by the order of which you inserted the values (I think this was
introduced in Ruby 1.9).

Yes. I would rely on that feature for debug printing purposes only
because the order is not fixed. If you build an ordered structure
(Array) and then copy that into a Hash I think you are doing too much
work because to process items in order you can already traverse the
Array.

Apart from that I agree with Jesus that the structure is much too
complex. It’s almost unreadable, a pain to process and very error-prone
(you rely on a certain structure which isn’t enforced at all). You
should definitely switch to an object structure with meaningful
entities.

Agree as well. Classes Struct and OpenStruct go a long way in making
this much more readable. Also the usage of more telling names than
“hn2” will greatly help.

Kind regards

robert