Il metodo <=>
deve restituire -1
, 0
o 1
per "minore di", "uguale a" e "maggiore di", rispettivamente. Per alcuni tipi di oggetti ordinabili, è normale basare l'ordinamento su più proprietà. I seguenti lavori, ma penso che sembra goffo:C'è una bella sintassi per il confronto complesso?
class LeagueStats
attr_accessor :points, :goal_diff
def initialize pts, gd
@points = pts
@goal_diff = gd
end
def <=> other
compare_pts = points <=> other.points
return compare_pts unless compare_pts == 0
goal_diff <=> other.goal_diff
end
end
Provarlo:
[
LeagueStats.new(10, 7),
LeagueStats.new(10, 5),
LeagueStats.new(9, 6)
].sort
# => [
# #<LS @points=9, @goal_diff=6>,
# #<LS @points=10, @goal_diff=5>,
# #<LS @points=10, @goal_diff=7>
# ]
Perl tratta 0
come un valore falso, che permette il confronto complessi con differenti sintassi:
{
return ($self->points <=> $other->points) ||
($self->goal_diff <=> $other->goal_diff);
}
Trovo la caduta attraverso 0
tramite l'operatore ||
semplice da leggere ed elegante. Una cosa che mi piace dell'uso di ||
è il cortocircuito dei calcoli una volta che il confronto ha un valore.
Non riesco a trovare nulla di simile in Ruby. Ci sono modi migliori per costruire lo stesso complesso di confronti (o qualsiasi altra cosa che preleva il primo elemento diverso da zero), idealmente senza dover calcolare tutti i valori in anticipo?
Questo è bello, ma mi piacerebbe che LeagueStats abbia un ordinamento inerente, è quello per cui sono. –
@NeilSlater, OK, ho aggiunto un altro codice derivato dalla risposta di Sawa. – falsetru