# How does one sort hash of hashes by multiple values?

**URL:** <https://rubytalk.org/t/how-does-one-sort-hash-of-hashes-by-multiple-values/22185>\
**Category:** ruby-talk\
**Created:** [5 November 2005 02:22 UTC](https://rubytalk.org/t/how-does-one-sort-hash-of-hashes-by-multiple-values/22185 "2005-11-05T02:22:09Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![joe.yakich](https://avatars.discourse-cdn.com/v4/letter/j/bc79bd/32.png) [@joe.yakich](https://rubytalk.org/u/joe.yakich)\
**Post date:** [5 November 2005 02:22 UTC](https://rubytalk.org/t/how-does-one-sort-hash-of-hashes-by-multiple-values/22185/1 "2005-11-05T02:22:09Z")

</div>

Imagine I have this data structure:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8858]['name'] = 'goober'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8858]['sort\_date'] = 19991231

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[2004]['name'] = 'goober'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[2004]['sort\_date'] = '20010416'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8872]['name'] = 'pyle'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8872]['sort\_date'] = '20010416'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[89]['name'] = 'hogan'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[89]['sort\_date'] = '2004 0918'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[9]['name'] = 'homer'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[9]['sort\_date'] = '19980718'

How does one sort it first by the name value, then by the sort\_date  
value? (So that the name == 'goober' items appear before the others,  
and the very first element returned by the sort would be  
@my\_hash[8858]?)

I tried searching a bit (the FAQ and google) , but came up empty; sorry  
if this is a noob question. (Although, I am a ruby noob, so...)

TIA!

Joe

---

<div class="post-metadata">

**Author:** ![Zach\_Dennis1](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@Zach\_Dennis1](https://rubytalk.org/u/Zach_Dennis1)\
**Post date:** [5 November 2005 02:41 UTC](https://rubytalk.org/t/how-does-one-sort-hash-of-hashes-by-multiple-values/22185/2 "2005-11-05T02:41:02Z")

</div>

There is probably a cleaner way to do this but...

sorted\_keys = @my\_hash.keys.sort do |a,b|  
&nbsp;&nbsp;&nbsp;next result unless res=(@my\_hash[a]['name']\<=\>@my\_hash[b]['name']) == 0  
&nbsp;&nbsp;&nbsp;@my\_hash[a]['sort\_date']\<=\>@my\_hash[b]['sort\_date']  
end

Then since you have your sorted keys you can iterate over each item based on your sorted\_keys array.

Zach

> **···**
>
> joe.yakich@gmail.com wrote:
> 
> > Imagine I have this data structure:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8858]['name'] = 'goober'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8858]['sort\_date'] = 19991231
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[2004]['name'] = 'goober'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[2004]['sort\_date'] = '20010416'
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8872]['name'] = 'pyle'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8872]['sort\_date'] = '20010416'
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[89]['name'] = 'hogan'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[89]['sort\_date'] = '2004 0918'
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[9]['name'] = 'homer'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[9]['sort\_date'] = '19980718'
> > 
> > How does one sort it first by the name value, then by the sort\_date  
> > value? (So that the name == 'goober' items appear before the others,  
> > and the very first element returned by the sort would be  
> > @my\_hash[8858]?)
> > 
> > I tried searching a bit (the FAQ and google) , but came up empty; sorry  
> > if this is a noob question. (Although, I am a ruby noob, so...)

---

<div class="post-metadata">

**Author:** ![W\_James](https://avatars.discourse-cdn.com/v4/letter/w/e274bd/32.png) [@W\_James](https://rubytalk.org/u/W_James)\
**Post date:** [5 November 2005 02:52 UTC](https://rubytalk.org/t/how-does-one-sort-hash-of-hashes-by-multiple-values/22185/3 "2005-11-05T02:52:09Z")

</div>

require 'pp'

my\_hash = Hash.new { |hash, key| hash[key] = Hash.new }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[8858]['name'] = 'goober'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[8858]['sort\_date'] = '19991231'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[2004]['name'] = 'goober'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[2004]['sort\_date'] = '20010416'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[8872]['name'] = 'pyle'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[8872]['sort\_date'] = '20010416'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[89]['name'] = 'hogan'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[89]['sort\_date'] = '20040918'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[9]['name'] = 'homer'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_hash[9]['sort\_date'] = '19980718'

pp my\_hash.sort\_by{|x| [x.last['name'], x.last['sort\_date'] ] }

----------------------------\>

[[8858, {"name"=\>"goober", "sort\_date"=\>"19991231"}],  
[2004, {"name"=\>"goober", "sort\_date"=\>"20010416"}],  
[89, {"name"=\>"hogan", "sort\_date"=\>"20040918"}],  
[9, {"name"=\>"homer", "sort\_date"=\>"19980718"}],  
[8872, {"name"=\>"pyle", "sort\_date"=\>"20010416"}]]

> **···**
>
> joe.yakich@gmail.com wrote:
> 
> > Imagine I have this data structure:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8858]['name'] = 'goober'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8858]['sort\_date'] = 19991231
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[2004]['name'] = 'goober'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[2004]['sort\_date'] = '20010416'
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8872]['name'] = 'pyle'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8872]['sort\_date'] = '20010416'
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[89]['name'] = 'hogan'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[89]['sort\_date'] = '2004 0918'
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[9]['name'] = 'homer'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[9]['sort\_date'] = '19980718'
> > 
> > How does one sort it first by the name value, then by the sort\_date  
> > value? (So that the name == 'goober' items appear before the others,  
> > and the very first element returned by the sort would be  
> > @my\_hash[8858]?)
> > 
> > I tried searching a bit (the FAQ and google) , but came up empty; sorry  
> > if this is a noob question. (Although, I am a ruby noob, so...)
> > 
> > TIA!
> > 
> > Joe

---

<div class="post-metadata">

**Author:** ![Zach\_Dennis1](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@Zach\_Dennis1](https://rubytalk.org/u/Zach_Dennis1)\
**Post date:** [5 November 2005 02:43 UTC](https://rubytalk.org/t/how-does-one-sort-hash-of-hashes-by-multiple-values/22185/4 "2005-11-05T02:43:13Z")

</div>

zdennis wrote:

> **···**
>
> > joe.yakich@gmail.com wrote:
> > 
> > > Imagine I have this data structure:
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8858]['name'] = 'goober'  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8858]['sort\_date'] = 19991231
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[2004]['name'] = 'goober'  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[2004]['sort\_date'] = '20010416'
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8872]['name'] = 'pyle'  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[8872]['sort\_date'] = '20010416'
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[89]['name'] = 'hogan'  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[89]['sort\_date'] = '2004 0918'
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[9]['name'] = 'homer'  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@my\_hash[9]['sort\_date'] = '19980718'
> > > 
> > > How does one sort it first by the name value, then by the sort\_date  
> > > value? (So that the name == 'goober' items appear before the others,  
> > > and the very first element returned by the sort would be  
> > > @my\_hash[8858]?)
> > > 
> > > I tried searching a bit (the FAQ and google) , but came up empty; sorry  
> > > if this is a noob question. (Although, I am a ruby noob, so...)
> > 
> > There is probably a cleaner way to do this but...
> > 
> > sorted\_keys = @my\_hash.keys.sort do |a,b|  
> > &nbsp;&nbsp;next result unless res=(@my\_hash[a]['name']\<=\>@my\_hash[b]['name']) == 0  
> > &nbsp;&nbsp;@my\_hash[a]['sort\_date']\<=\>@my\_hash[b]['sort\_date']  
> > end
> 
> That should be:
> 
> sorted\_keys = @my\_hash.keys.sort do |a,b|  
> &nbsp;&nbsp;&nbsp;next result unless result=(@my\_hash[a]['name']\<=\>@my\_hash[b]['name']) == 0  
> &nbsp;&nbsp;&nbsp;@my\_hash[a]['sort\_date']\<=\>@my\_hash[b]['sort\_date']  
> end
