Who are we?

We are a group of enthousiastic people working for Nedap, a Dutch company with a single goal: solve problems.

Search

Entries in sort_by (1)

Sunday
Jul292007

Sort, sort_by and group_by

I wanted to put the spotlight on some small but very useful ruby on rails functions: sort, sort_by and group_by.

Let's start with sort and sort_by. Its basic function should not come as a surprise: it sorts a list.

[1,3,2,4].sort => [1,2,3,4]

These functions really shine when you use objects inside the list.

a = { :key => 0, :value => 'a', :extra => 0 }
b = { :key => 1, :value => 'b', :extra => 0 }
c = { :key => 2, :value => 'c', :extra => 1 }
d = { :key => 3, :value => 'd', :extra => 1 }

[a,c,d,b].sort_by{ |i| i[:key] } => [a,b,c,d]

The previous example already contains the correct objects to demonstrate the use of group_by so we just give that example now.

[a,b,c,d].group_by{ |i| i[:extra] } => [ 0=>[a,b], 1=>[c,d] ]

As you can see this gives us the power of the SQL group_by statements right inside ruby. Sure, this cannot beat the speed of the SQL equivalent. But sometimes when speed is not really an issue or when you just can't query the right results, group_by can be a real life-saver.

As a bonus, when you want to group_by or sort_by functions on objects, you can use this pretty shorthand:

[a,b,c,d].group_by(&:length) => [ 3 => [a,b,c,d] ]

If you are wondering why the above works, it is just basic ruby. Any function that is defined to receive a &block can be called by either giving it a block of code in parenthesis or by passing it a proc object. The &:length is just shorthand for &proc{ |i| i.length }. Too bad you can't pass it arguments using the shorthand, then you'd be able to write:

[a,b,c,d].group_by(&:fetch, :key)

Hope you find this useful, if anyone knows if the above code is indeed possible in another form, please comment!

Update: I recently found out you can also use arrays in combination with these functions. So you can sort by multiple values. If you pass array [a,b] to a sort function it will sort by a and then sort by b. Very handy!