# How to sort a multi-elements array

**URL:** <https://www.ruby-forum.com/t/how-to-sort-a-multi-elements-array/139163>\
**Category:** Ruby\
**Created:** [May 31, 2008, 7:37pm UTC](https://www.ruby-forum.com/t/how-to-sort-a-multi-elements-array/139163 "2008-05-31T19:37:53Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kadoudal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f0a364/32.png) [@kadoudal](https://www.ruby-forum.com/u/kadoudal)\
**Post date:** [May 31, 2008, 7:37pm UTC](https://www.ruby-forum.com/t/how-to-sort-a-multi-elements-array/139163/1 "2008-05-31T19:37:53Z")

</div>

I know how to sort an array with 2 elements… that’s the only example  
I could fin on Array#sort…  
but what if … I need to sort an array like this one :

anArray = [[1, “joe”, 4], [2, “arthur”, 2], [5, “william”, 3], [16,  
“bob”, 1], [20, “ernesto”, 17], [27, “julia”, 1], [28, “barbara”, 2] ]

sorting on third-element (highest ranking) , and second-element  
(nickname)

aSortedArray = [[20, “ernesto”, 17], [1, “joe”, 4], 5, “william”, 3],  
[2, “arthur”, 2], [28, “barbara”, 2], [16, “bob”, 1] ]

any doc link where this is explained ?

thanks a lot for your tip

---

<div class="post-metadata">

**Author:** ![kadoudal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f0a364/32.png) [@kadoudal](https://www.ruby-forum.com/u/kadoudal)\
**Post date:** [May 31, 2008, 7:43pm UTC](https://www.ruby-forum.com/t/how-to-sort-a-multi-elements-array/139163/2 "2008-05-31T19:43:45Z")

</div>

On Saturday 31 May 2008, Erwin wrote:

> aSortedArray = [[20, “ernesto”, 17], [1, “joe”, 4], 5, “william”, 3],  
> [2, “arthur”, 2], [28, “barbara”, 2], [16, “bob”, 1] ]
> 
> any doc link where this is explained ?
> 
> thanks a lot for your tip

You can do this:

aSortedArray = anArray.sort do |a, b|  
if a[2] == b[2] then a[1] \<=\> b[1]  
else a[2] \<=\> b[2]  
end  
end

If the third element of the two subarrays are equal, then the block  
returns  
the result of the comparison of the second elements (using \<=\>),  
otherwise it  
returns the result of the comparison of the third elements, again using  
\<=\>.

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![kadoudal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f0a364/32.png) [@kadoudal](https://www.ruby-forum.com/u/kadoudal)\
**Post date:** [May 31, 2008, 7:45pm UTC](https://www.ruby-forum.com/t/how-to-sort-a-multi-elements-array/139163/3 "2008-05-31T19:45:30Z")

</div>

On 31.05.2008 19:31, Erwin wrote:

> aSortedArray = [[20, “ernesto”, 17], [1, “joe”, 4], 5, “william”, 3],  
> [2, “arthur”, 2], [28, “barbara”, 2], [16, “bob”, 1] ]
> 
> any doc link where this is explained ?

As always, use #sort with a block or #sort\_by - the number of elements  
in those arrays is irrelevant, you just need to decide which elements  
you want to pick as sort key.

an\_array.sort\_by {|a,b,c| [c,b]}  
an\_array.sort {|(a,b,c),(d,e,f)| [c,b] \<=\> [f,e]}  
an\_array.sort do |(a,b,c),(d,e,f)|  
x = c \<=\> f  
x == 0 ? b \<=\> e : x  
end

Btw, your data looks like it could benefit from using Struct and also  
benefit from the automatically implemented \<=\>, i.e.

Person = Struct.new :age, :name, :position

an\_array = [  
Person.new(4, “joe”, 1),  
Person.new(2, “arthur”, 2),  
Person.new(3, “william”, 5),  
]

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![kadoudal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f0a364/32.png) [@kadoudal](https://www.ruby-forum.com/u/kadoudal)\
**Post date:** [June 1, 2008, 8:35am UTC](https://www.ruby-forum.com/t/how-to-sort-a-multi-elements-array/139163/4 "2008-06-01T08:35:38Z")

</div>

On 31 mai, 19:40, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > (nickname)  
> > an\_array.sort\_by {|a,b,c| [c,b]}
> 
> an\_array = [  
> Person.new(4, “joe”, 1),  
> Person.new(2, “arthur”, 2),  
> Person.new(3, “william”, 5),  
> ]
> 
> Kind regards
> 
> ```
> robert
> 
> ```

thanks Robert , I’ll write that in my NoteTaker Ruby book !!

---

<div class="post-metadata">

**Author:** ![kadoudal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f0a364/32.png) [@kadoudal](https://www.ruby-forum.com/u/kadoudal)\
**Post date:** [April 7, 2009, 5:30am UTC](https://www.ruby-forum.com/t/how-to-sort-a-multi-elements-array/139163/5 "2009-04-07T05:30:43Z")

</div>

Hi,

Was going through these older posts and have a similar question. I  
have a nested array that contains a date and a filename. I’m trying to  
sort by file date.

The array is in the form:

SortedFiles = [[200904031109, “filea.txt”], [200904031337,  
“fileb.txt”], [200904031110, “filec.xt”] ]

What I was trying to do was:

SortedFiles.sort { |[[a,b],[x,y]] a \< x | }

That, unfortunately, did not work. I’m using Ruby 1.8.5 btw. Can anyone  
help out?

Thanks,  
Alex

Stefano C. wrote:

> On Saturday 31 May 2008, Erwin wrote:
> 
> > aSortedArray = [[20, “ernesto”, 17], [1, “joe”, 4], 5, “william”, 3],  
> > [2, “arthur”, 2], [28, “barbara”, 2], [16, “bob”, 1] ]
> > 
> > any doc link where this is explained ?
> > 
> > thanks a lot for your tip
> 
> You can do this:
> 
> aSortedArray = anArray.sort do |a, b|  
> if a[2] == b[2] then a[1] \<=\> b[1]  
> else a[2] \<=\> b[2]  
> end  
> end
> 
> If the third element of the two subarrays are equal, then the block  
> returns  
> the result of the comparison of the second elements (using \<=\>),  
> otherwise it  
> returns the result of the comparison of the third elements, again using  
> \<=\>.
> 
> I hope this helps
> 
> Stefano

---

<div class="post-metadata">

**Author:** ![kadoudal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f0a364/32.png) [@kadoudal](https://www.ruby-forum.com/u/kadoudal)\
**Post date:** [April 7, 2009, 6:32am UTC](https://www.ruby-forum.com/t/how-to-sort-a-multi-elements-array/139163/6 "2009-04-07T06:32:52Z")

</div>

On 4/6/09, Alexey Z. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> What I was trying to do was:
> 
> SortedFiles.sort { |[[a,b],[x,y]] a \< x | }
> 
> That, unfortunately, did not work. I’m using Ruby 1.8.5 btw. Can anyone  
> help out?

SortedFiles.sort\_by {|date, fname| date}  
or:  
SortedFiles.sort {|record1,record2| record1[0]\<=\>record2[0]}

---

<div class="post-metadata">

**Author:** ![kadoudal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f0a364/32.png) [@kadoudal](https://www.ruby-forum.com/u/kadoudal)\
**Post date:** [April 7, 2009, 2:29pm UTC](https://www.ruby-forum.com/t/how-to-sort-a-multi-elements-array/139163/7 "2009-04-07T14:29:23Z")

</div>

On Tue, Apr 7, 2009 at 12:31 AM, Christopher D.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

> > “fileb.txt”], [200904031110, “filec.xt”] ]  
> > SortedFiles.sort {|record1,record2| record1[0]\<=\>record2[0]}

Since you are sorting on the first element of each array you can just  
use  
SortedFiles.sort

Array comparison with another array works by using the comparison of the  
first pair of elements which aren’t equal, so [1,1] \< [2,0] \< [2,1]

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)
