I'm not sure why nil doesn't support <=>. In most sorting cases, nil is less than everything else, so it would seem safe enough if it were extended with that. You've run into this issue if you get:
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.<=>
So, what's the workaround?
Say you want to sort an array of task assignments their project name. My first hack was to write a lot of code like the following to try to get around it:
task_assignment.sort { |x,y|
a = x.try(:project).try(:name)
b = y.try(:project).try(:name)
if a && b
a <=> b
elsif !a && !b
0
else
left ? 1 : -1
end
}
I knew this was a little long, so I spoke with Jim who showed me a much cleaner method:
task_assignment.sort_by { |ta| ta.try(:project).try(:name) || '' }
With this code, nil, a task assignment without a project, or a project without a name are equivalent to a task assignment with a project name of ''. It's not functionally equivalent to the code above it that would weigh nil even less than '', but it's fine.
2 comments:
Nil-Safe max and min works similarly. For example:
max = series.max {|a,b| (a || 0) <=> (b || 0)}
Thanks, Chuck!
Post a Comment