IN sql we can pass two arguments to the 'order by' component, and it
will order the results by A, and then B in the cases where A is the
same.
Can anyone think of a way to do the same thing with a ruby array? For
example, if the array holds objects that have attributes/methods
"lastname" & "firstname", to order the objects in a similar way to the
sql query?
Can anyone think of a way to do the same thing with a ruby array? For
example, if the array holds objects that have attributes/methods
"lastname" & "firstname", to order the objects in a similar way to the
sql query?
On Mon, Aug 11, 2008 at 5:16 PM, Max Williams <toastkid.williams@gmail.com> wrote:
IN sql we can pass two arguments to the 'order by' component, and it
will order the results by A, and then B in the cases where A is the
same.
Can anyone think of a way to do the same thing with a ruby array? For
example, if the array holds objects that have attributes/methods
"lastname" & "firstname", to order the objects in a similar way to the
sql query?
Here's one way: the trick is to create an array with the fields you want
to order by in the sort_by block:
Hope this helps,
Jesus.
That's a neat trick, thanks! I actually like the first one better
though as you can swap a & b around in each test to get (eg) sorted by
name ascending and then a date field descending.
In theory this is less efficient since there are two Array instances
created per comparison. If you go for the Array solution, using #sort_by is probably better:
objects.sort_by {|a| [a.lastname, a.firstname]}
Kind regards
robert
···
On Mon, Feb 18, 2013 at 6:42 PM, Jack V. <lists@ruby-forum.com> wrote:
I would just create an array containing the parts you want to compare:
That's a neat trick, thanks! I actually like the first one better
though as you can swap a & b around in each test to get (eg) sorted by
name ascending and then a date field descending.
This is often true as sort_by only calls methods on each object once, but it
is not universally true -- see module Enumerable - RDoc Documentation for more
information, and run some benchmarks for your use case if it's a big issue.
# not delegating anything else because this is explicitly a throwaway
# object used only inside a sort_by block
end
and then you have
a.sort_by {|x| [x.name, RevCmp.new(x.date)]}
you could even use a top-level method so you can say
a.sort_by {|x| [x.name, descending(x.date)]}
where descending(x) returns RevCmp.new(x)
You could even mix it into object to get
a.sort_by {|x| [x.name, x.date._descending_]}
where I use the underscores as a cosmetic way of making it stand out
inside the sort block
martin
···
On Mon, Aug 11, 2008 at 8:48 AM, Erik Veenstra <erikveen@gmail.com> wrote:
That's a neat trick, thanks! I actually like the first one better
though as you can swap a & b around in each test to get (eg) sorted by
name ascending and then a date field descending.