Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何将自定义比较器传递给;排序;?_Ruby_Sorting_Comparator - Fatal编程技术网

Ruby 如何将自定义比较器传递给;排序;?

Ruby 如何将自定义比较器传递给;排序;?,ruby,sorting,comparator,Ruby,Sorting,Comparator,类A具有以下比较器: class A attr_accessor x def my_comparator(a) x**2 <=> (a.x)**2 end end A类 属性存取器x def my_比较器(a) x**2(a.x)**2 结束 结束 我想使用此比较器对数组进行排序,其中每个项都属于A类: class B def my_method items.sort!(<how can I pass my_comparator here

A
具有以下比较器:

class A
  attr_accessor x

  def my_comparator(a)
    x**2 <=> (a.x)**2
  end
end
A类
属性存取器x
def my_比较器(a)
x**2(a.x)**2
结束
结束
我想使用此比较器对数组进行排序,其中每个项都属于A类:

class B
  def my_method
    items.sort!(<how can I pass my_comparator here ?>)
  end
end
B类
def my_方法
物品。分类!()
结束
结束

如何将
我的\u比较器传递到
排序

这两种方法都应该有效:

items.sort_by! { |a| (a.x)**2 }
items.sort! { |a1,a2| a1.my_comparator(a2) }
定义您自己的
,并包括可比较的。这是来自:

这将在内部调用
:my_comparator.to_proc
,返回一个块

proc {|x,y| x.my_comparator(y)}
从而将这个答案简化为本·阿尔伯特的答案


(但我同意Phrogz的观察,如果这是类的自然顺序,那么你应该使用锡人的答案。)

如果你想在不同的地方重用这些比较器,最好将它们定义为一个类,而不是每次都重写相同的lambda表达式

这是基于Java对可比接口的实现:

module Comparator
  def compare(a, b)
    raise NotImplementedError, 'must implement this method'
  end

  def to_proc
    ->(a, b) { compare(a, b) }
  end
end

class LengthComparator
  include Comparator

  def compare(a, b)
    a.length <=> b.length
  end
end

class ReverseLengthComparator < LengthComparator
  def compare(a, b)
    -super
  end
end
模块比较器
def比较(a、b)
raise NOTEImplementedError,“必须实现此方法”
结束
def to_proc
->(a,b){比较(a,b)}
结束
结束
类长度比较器
包括比较器
def比较(a、b)
a、 长度
结束
结束
类反向长度比较器<长度比较器
def比较(a、b)
-超级
结束
结束

您可以在#compare方法中实现比较逻辑。然后可以像这样使用这个类:
array.sort(&MyCustomComparator.new)
。它本质上可以归结为一个lambda表达式,但在我看来它支持更多的可重用性。

这是好的和正确的,但是@theTinMan的答案更适合自定义类。这是我一直在寻找的答案,而不是上面的OO垃圾。或者,针对这个问题:
alias\u method:,:my\u comparator
+1。很好的catch@Phrogz,不过首先调用方法
会更像Ruby。在我的例子中,我有几个比较器,所以我不想用
my_comparator
覆盖
。我添加了一些使用lambdas的示例,可以轻松地交换比较。实际上,你可以使用
items.sort!{x,yx.MyIa比较器y},但是如果这是类的默认排序行为,那么你应该考虑一下锡人下面的东西。
items.sort!(&:my_comparator)
proc {|x,y| x.my_comparator(y)}
module Comparator
  def compare(a, b)
    raise NotImplementedError, 'must implement this method'
  end

  def to_proc
    ->(a, b) { compare(a, b) }
  end
end

class LengthComparator
  include Comparator

  def compare(a, b)
    a.length <=> b.length
  end
end

class ReverseLengthComparator < LengthComparator
  def compare(a, b)
    -super
  end
end