# One SELECT, multiple sorts

**URL:** <https://www.ruby-forum.com/t/one-select-multiple-sorts/162435>\
**Category:** Rails\
**Created:** [March 9, 2009, 11:48pm UTC](https://www.ruby-forum.com/t/one-select-multiple-sorts/162435 "2009-03-09T23:48:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![partydrone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/a6a055/32.png) [@partydrone](https://www.ruby-forum.com/u/partydrone)\
**Post date:** [March 9, 2009, 11:48pm UTC](https://www.ruby-forum.com/t/one-select-multiple-sorts/162435/1 "2009-03-09T23:48:07Z")

</div>

I want to pull data from the database once, but do multiple sorts on  
different columns.

I’m pulling a list of products from the database. In my view, I want  
to create two select lists: one sorted by the product name; one sorted  
by part number. I know I can map the values into a new array or use  
“options\_from\_collection\_for\_select,” but I’m having a little trouble  
with sorting.

> > products.map { |p| [p.id, p.name] }.sort  
> > =\> [[7, “DataCollector”], [8, “DataTranslator”], [9, “DataMonitor”],  
> > [10, “DataExpress”], [11, “DataView”]]

The “sort” command sorts by the first item in each array, as can be  
seen by switching the values:

> > products.map { |p| [p.name, p.id] }.sort  
> > =\> [[“DataCollector”, 7], [“DataExpress”, 10], [“DataMonitor”, 9],  
> > [“DataTranslator”, 8], [“DataView”, 11]]

So, how do I get the sort order I want from the second example, but  
keep the structure from the first example so the select list will  
display correctly?

Thanks.

---

<div class="post-metadata">

**Author:** ![partydrone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/a6a055/32.png) [@partydrone](https://www.ruby-forum.com/u/partydrone)\
**Post date:** [March 9, 2009, 11:58pm UTC](https://www.ruby-forum.com/t/one-select-multiple-sorts/162435/2 "2009-03-09T23:58:04Z")

</div>

On Mar 9, 2009, at 3:47 PM, partydrone wrote:

> > > products.map { |p| [p.id, p.name] }.sort  
> > > So, how do I get the sort order I want from the second example, but  
> > > keep the structure from the first example so the select list will  
> > > display correctly?

products.sort\_by{|p| p.name}.map{|p| [p.name, p.id}

is one way.

-philip

---

<div class="post-metadata">

**Author:** ![partydrone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/a6a055/32.png) [@partydrone](https://www.ruby-forum.com/u/partydrone)\
**Post date:** [March 9, 2009, 11:58pm UTC](https://www.ruby-forum.com/t/one-select-multiple-sorts/162435/3 "2009-03-09T23:58:04Z")

</div>

On Mar 9, 10:47 pm, partydrone [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I want to pull data from the database once, but do multiple sorts on  
> different columns.
> 
> I’m pulling a list of products from the database. In my view, I want  
> to create two select lists: one sorted by the product name; one sorted  
> by part number. I know I can map the values into a new array or use  
> “options\_from\_collection\_for\_select,” but I’m having a little trouble  
> with sorting.
> 
> > > products.map { |p| [p.id, p.name] }.sort

sort takes a block - you can make it compare anyway you want with that  
block, eg [1,2,3].sort {|x,y| x \<=\> y} is the same as [1,2,3] but  
[1,2,3].sort {|x,y| y \<=\> x } would sort in opposite order and  
[1,2,3,4,5,6,7,8].sort {|x,y| (x%5) \<=\> (y%5)} sorts according to  
residue mod 5.

Fred

---

<div class="post-metadata">

**Author:** ![partydrone](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/a6a055/32.png) [@partydrone](https://www.ruby-forum.com/u/partydrone)\
**Post date:** [March 10, 2009, 12:02am UTC](https://www.ruby-forum.com/t/one-select-multiple-sorts/162435/4 "2009-03-10T00:02:45Z")

</div>

This works, too:

\<%= select\_tag(‘product[name]’, options\_for\_select(@products.map { |p|  
[p.name, p.id] }.sort)) %\>

Thanks, guys.
