Zuerst weg, lassen Sie uns Ihre Einbuchtung reparieren (und konvertieren Standard-Stil Ruby-Community-Codierung), so dass wir besser sehen, was los ist:
[1, 2, 3, 4, 5, 6].sort do |x, y|
if x.odd? && y.odd?
0
elsif x.odd?
-1
else
1
end
if (x.odd? && y.odd?) || (x.even? && y.even?)
x <=> y
end
end
Nun wird das Problem offensichtlich: Ihre Der erste Bedingungsausdruck ergibt 0
, -1
oder 1
, aber wird nichts mit diesem Wert getan. Der Wert wird nicht in einer Variablen gespeichert, nicht als Argument übergeben, nicht zurückgegeben. Es wird einfach ignoriert. Der gesamte Ausdruck ist ein NO-OP.
was bedeutet, dass das einzige, was diese zählt, ist:
if (x.odd? && y.odd?) || (x.even? && y.even?)
x <=> y
end
Diese Rückkehr wird 0
für zwei Elemente, die gleich sind, -1
oder 1
für zwei Elemente, die ungleich aber beide ungerade oder beide auch sind, und nil
(was zu sort
bedeutet "diese beiden Elemente sind nicht vergleichbar, sie haben keine definierte relative Reihenfolge") für Elemente, bei denen ein Element ungerade und eins ist gerade. Da sort
erfordert, dass alle Elemente vergleichbar sind, wird es dann abgebrochen.
Der einfachste Weg, um dieses Problem zu nähern würde wahrscheinlich das Array in Chancen und Evens zu partitionieren sein, sortieren sie getrennt, und sie dann verketten:
[1, 2, 3, 4, 5, 6].partition(&:odd?).map(&:sort).inject(:concat)
#=> [1, 3, 5, 2, 4, 6]
Oder es anders machen rund, sortieren sie einfach alle, und dann Partition (Thanks @Eric Duminil):
[1, 2, 3, 4, 5, 6].sort.partition(&:odd?).inject(:concat)
#=> [1, 3, 5, 2, 4, 6]
Schöner One-Liner. Sie könnten sogar 'map' entfernen, indem Sie zuerst sortieren und dann partitionieren:' [3, 2, 1, 5, 6, 4] .sort.partition (&: odd?). Inject (: concat) ' –
Oder' [1 , 2,3,4,5,6] .sort_by {| i | [ich.odd] ? 0: 1, i]} ' – Stefan
@Stefan. [Danke] (http://stackoverflow.com/a/42929315/6419007) –