# How to sort this nested hash

**URL:** <https://rubytalk.org/t/how-to-sort-this-nested-hash/65803>\
**Category:** ruby-talk\
**Created:** [2 July 2012 07:21 UTC](https://rubytalk.org/t/how-to-sort-this-nested-hash/65803 "2012-07-02T07:21:40Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [2 July 2012 07:21 UTC](https://rubytalk.org/t/how-to-sort-this-nested-hash/65803/1 "2012-07-02T07:21:40Z")

</div>

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'] }}}}

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Jesus\_Gabriel\_y\_Gala](https://avatars.discourse-cdn.com/v4/letter/j/96bed5/32.png) [@Jesus\_Gabriel\_y\_Gala](https://rubytalk.org/u/Jesus_Gabriel_y_Gala)\
**Post date:** [2 July 2012 07:52 UTC](https://rubytalk.org/t/how-to-sort-this-nested-hash/65803/2 "2012-07-02T07:52:53Z")

</div>

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 Mon, Jul 2, 2012 at 9:21 AM, yibin z. \<lists@ruby-forum.com\> 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'] }}}}

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [2 July 2012 12:24 UTC](https://rubytalk.org/t/how-to-sort-this-nested-hash/65803/3 "2012-07-02T12:24:57Z")

</div>

Hi,

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).

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.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Ryan\_Davis1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/ryan_davis1/32/1848_2.png) [@Ryan\_Davis1](https://rubytalk.org/u/Ryan_Davis1)\
**Post date:** [2 July 2012 09:44 UTC](https://rubytalk.org/t/how-to-sort-this-nested-hash/65803/4 "2012-07-02T09:44:21Z")

</div>

nit: s/sorted/ordered/g

> **···**
>
> On Jul 2, 2012, at 00:52 , Jesús Gabriel y Galán 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.

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [2 July 2012 12:40 UTC](https://rubytalk.org/t/how-to-sort-this-nested-hash/65803/5 "2012-07-02T12:40:23Z")

</div>

> 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

> **···**
>
> On Mon, Jul 2, 2012 at 2:24 PM, Jan E. \<lists@ruby-forum.com\> wrote:
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)
