Class A
has the following comparator:
class A attr_accessor x def my_comparator(a) x**2 <=> (a.x)**2 end end
I would like to use this comparator to sort an array where each item is of class A:
class B def my_method items.sort!(<how can I pass my_comparator here ?>) end end
How should I pass my_comparator
to sort!
?
Using a comparator, we can sort the elements based on data members. For instance, it may be on roll no, name, age, or anything else. Method of Collections class for sorting List elements is used to sort the elements of List by the given comparator.
Comparator functions are deprecated in Python; use key functions instead. if condition: return True else: return False should be return condition . Dictionaries do not preserve order. If you want a sorted dictionary you should use OrderedDict from the collections module.
In order to sort Employee object on different criteria, we need to create multiple comparators e.g. NameComparator, AgeComparator, and SalaryComparator, this is known as custom sorting in Java. This is different from the natural ordering of objects, provided by the compareTo() method of java.
Define your own <=>
, and include Comparable. This is from the Comparable doc:
class SizeMatters include Comparable attr :str def <=>(an_other) str.size <=> an_other.str.size end def initialize(str) @str = str end def inspect @str end end s1 = SizeMatters.new("Z") s2 = SizeMatters.new("YY") s3 = SizeMatters.new("XXX") s4 = SizeMatters.new("WWWW") s5 = SizeMatters.new("VVVVV") s1 < s2 #=> true s4.between?(s1, s3) #=> false s4.between?(s3, s5) #=> true [ s3, s2, s5, s4, s1 ].sort #=> [Z, YY, XXX, WWWW, VVVVV]
You don't actually have to include Comparable, but you get extra functionality for free if you do that after having defined <=>
.
Otherwise, you can use Enumerable's sort
with a block if your objects implement <=>
already.
Another way to use several different comparisons is to use lambdas. This uses the new 1.9.2 declaration syntax:
ascending_sort = ->(a,b) { a <=> b } descending_sort = ->(a,b) { b <=> a } [1, 3, 2, 4].sort( & ascending_sort ) # => [1, 2, 3, 4] [1, 3, 2, 4].sort( & descending_sort ) # => [4, 3, 2, 1] foo = ascending_sort [1, 3, 2, 4].sort( & foo ) # => [1, 2, 3, 4]
Both of these should work:
items.sort_by! { |a| (a.x)**2 } items.sort! { |a1,a2| a1.my_comparator(a2) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With