Noch mal der <=>-Operator 0

Posted by fwoeck
on Wednesday, April 22

Die Methode sort ist so genügsam, dass es ihr reicht, wenn der <=>-Operator definiert ist. Damit lassen sich bequem angepasste Sortiermethoden – z.B. für ActiveRecord-Objekte – schreiben:

>> cs = Contact.all(:limit => 10)
=> [#<Contact id: "a372b1f0-c368-faf3-2dba-49db1a07e2a0", ...

>> cs.sort
NoMethodError: undefined method `<=>' for #<Contact: ...

>> class Contact
>>   def <=>(other)
>>     self.primary_address_postalcode.to_i <=> other.primary_address_postalcode.to_i
>>   end
>> end

>> cs.sort
=> [#<Contact id: "15890900-fa74-58ac-a5f6-49db1c37f4c6", ...

>> cs.map(&:primary_address_postalcode)
=> ["60320", nil, "01187", "10785", "70178", "61231", "10969", "60313", "34123", "65189"]

>> cs.sort.map(&:primary_address_postalcode)
=> [nil, "01187", "10785", "10969", "34123", "60313", "60320", "61231", "65189", "70178"]

sort_by

In einigen Fällen ist die Methode “sort_by” die schnellere Lösung: sie funktioniert ähnlich wie map. Hier klappt das nur eingeschränkt, denn sie benutzt den <=>-Operator direkt auf dem Tabelleninhalt und gibt auf, sobald einer davon NIL ist:

>> cs.sort_by(&:primary_address_postalcode)

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.<=>

Arrays durchmischen 0

Posted by fwoeck
on Wednesday, September 24

Eine Möglichkeit, ein Array zufällig anzuordnen besteht in der Neudefinition der Ufo-Methode von sort:

>>  [1,2,3,4,5,6,7,8].sort {|x,y| [-1,0,1].rand}
=> [4, 2, 1, 5, 7, 6, 3, 8]
>>  [1,2,3,4,5,6,7,8].sort {|x,y| [-1,0,1].rand}
=> [8, 4, 1, 3, 2, 6, 7, 5]

Etwas einfacher:

>> (0..10).to_a.sort_by{rand}
=> [5, 4, 3, 1, 2, 9, 6, 7, 10, 0, 8]