DEV Community

Beth Haubert
Beth Haubert

Posted on • Updated on

A new (to me) Enumerable method

So I was helping one of our front-end devs on a view the other day and he needed a collection of objects to be in a very specific order. The problem was that it required a very ugly and somewhat confusing query:

@in_progress = migration_request_group.current_migration_requests.sort_by { |x|
 x.in_progress_in_group? ? 0 : 1 }.sort_by { |x| x.pending? ? 0 : 1 }

It first sorts the current_migration_requests so that if the request currently being looped over is in_progress_in_group?, it gets moved to the first position in the array, otherwise it's moved to the second position. And then it checks if that request is pending. If so, it get's moved into the first position. If you're just looking at the code for the first time, it's not easy to understand at all.

I knew there had to be a better way. I just didn't know what that better way was...

Fortunately, I'm on a team of seasoned Ruby developers who helped me out. It turns out there's this method called partition that's actually been around a while.

pending, rest = migration_request_group.current_migration_requests.partition(&:pending?)
in_progress, rest = rest.partition(&:in_progress_in_group?)
@in_progress = pending + in_progress + rest

Here's how it works:
There are two arrays: pending and rest. The first one, pending, will store any objects that the block finds true, while rest will store the rest of the objects. Then I do another partition block where I take that existing rest array and split it into two more arrays: in_progress and, again, rest.
Then I combine the arrays in the required order. It may take up three lines of code instead of one, but I believe it's much clearer.

Top comments (0)