在块传递时,数组#sorting如何工作?
我有一个理解如何array.sort{ |x,y| block }
array.sort{ |x,y| block }
正常工作,因此如何使用它?
Ruby文档的一个例子:
a = [ "d", "a", "e", "c", "b" ] a.sort #=> ["a", "b", "c", "d", "e"] a.sort { |x,y| y <=> x } #=> ["e", "d", "c", "b", "a"]
在你的例子中
a.sort
相当于
a.sort { |x, y| x <=> y }
正如你所知道的,为了对一个数组进行sorting,你需要能够比较它的元素(如果你怀疑的话,试着实现任何sortingalgorithm,而不使用任何比较,否则<
, >
, <=
或>=
)。
你提供的块实际上是一个函数,它将被sort
algorithm调用来比较两个项目。 那就是x
和y
将始终是sort
algorithm在执行过程中所select的input数组的一些元素。
sort
algorithm将假定该比较函数/块将满足方法<=>
的要求:
- 如果x <y,则返回-1
- 如果x = y,则返回0
- 如果x> y,则返回1
如果未能提供足够的比较函数/块,将导致数组的顺序未定义。
你现在应该明白为什么
a.sort { |x, y| x <=> y }
和
a.sort { |x, y| y <=> x }
以相反的顺序返回相同的数组。
要详细说明Tate Johnson添加的内容,如果您在任何类上实现比较函数<=>
,则获得以下内容
- 你可以在你的类中包含
Comparable
模块,它会自动为你定义以下方法:between?
,==
,>=
,<
,<=
和>
。 - 你的类的实例现在可以使用缺省(即没有参数)调用进行
sort
来sort
。
请注意,在ruby的标准库( Bignum
, Array
, File::Stat
, Fixnum
, String
, Time
等等)中,已经提供了<=>
方法。
当你有一个数组,比如sorting整数时, sort
方法对于正确sort
元素非常简单 – 首先是较小的数字,最后是较大的数字。 那是当你使用普通的sort
,没有阻止。
但是,当您sorting其他对象时,可能需要提供一种方法来比较(每个)其中两个。 假设你有一个Person
类的对象数组。 你可能不知道对象bob
是否比对象mike
(即类Person
没有方法<=>
实现)更大。 在这种情况下,您需要提供一些代码来解释按照哪种顺序将这些对象sorting为sort
方法。 这是块forms踢的地方。
people.sort{|p1,p2| p1.age <=> p2.age} people.sort{|p1,p2| p1.children.count <=> p2.children.count}
在所有这些情况下, sort
方法以相同的方式对它们进行sort
– 使用相同的algorithm。 比较逻辑有什么不同?
@OscarRyz的回复在我如何sorting的问题上为我解决了很多问题,
{ |x, y| y <=> x }
基于我的理解,我在这里提供了在每个比较上面的块结果之后数组的状态。
注意:从ruby-forum获得了打印参数块e1,e2的值的参考
1.9.3dev :001 > a = %w(deawfk) 1.9.3dev :003 > a.sort { |e1, e2| p [e2, e1]; e2 <=> e1 } ["w", "d"] ["k", "w"] ["k", "d"] ["k", "e"] ["k", "f"] ["k", "a"] ["f", "a"] ["d", "f"] ["d", "a"] ["d", "e"] ["e", "f"] => ["w", "k", "f", "e", "d", "a"]
在每次比较之后,运行时的猜测数组状态:
[e2, e1] Comparsion Result Array State ["w", "d"] 1 ["w", "e", "a", "d", "f", "k"] ["k", "w"] -1 ["w", "e", "a", "d", "f", "k"] ["k", "d"] 1 ["w", "e", "a", "k", "f", "d"] ["k", "e"] 1 ["w", "k", "a", "e", "f", "d"] ["k", "f"] 1 ["w", "k", "a", "e", "f", "d"] ["k", "a"] 1 ["w", "k", "a", "e", "f", "d"] ["f", "a"] 1 ["w", "k", "f", "e", "a", "d"] ["d", "f"] -1 ["w", "k", "f", "e", "a", "d"] ["d", "a"] 1 ["w", "k", "f", "e", "d", "a"] ["d", "e"] -1 ["w", "k", "f", "e", "d", "a"] ["e", "f"] -1 ["w", "k", "f", "e", "d", "a"] (Result)
谢谢,
Jignesh
<=>
是一个返回方法是ruby( self.<=>( argument )
)
- -1如果self <argument
- 0如果自我==参数
- 1如果自我>论证
x
和y
是数组的项目。 如果没有提供块,则sort
函数使用x<=>y
,否则块的结果表示x是否应该在y之前。
array.sort{|x, y| some_very_complicated_method(x, y) }
这里如果some_very_complicated_method(x,y)返回的是<0,则认为x <y,等等…
一些杂项点:
-
x
和y
被称为块参数。 sorting方法基本上是这样说的:“我给你x和y,你决定是否应该先来个x或y,然后我会照顾无聊的东西, -
<=>
被称为飞船运营商 。
在:
a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"]
什么是x和y?
x
和y
是通过sortingalgorithm进行比较的元素。
这对自定义类定义哪个元素应该在另一个之前是有用的。
对于基本数据(数字,string,date等),自然顺序是预先定义的,但是对于客户元素(即员工),您可以定义谁比谁先行。 这个块给你一个定义的机会。
在y <=> x上会发生什么?
在那里,他们按降序比较元素(那些具有“较高”值的元素将首先)而不是自然顺序( x<=>y
)
<=>
方法代表“compareTo”,如果元素是等价的,则返回0;如果x
先于y
,则返回<
0;如果x
追随y
,则返回>
0
我相信| x,y | y <=> x是按照降序顺序比较两个元素,如下所示: http : //www.ruby-doc.org/core-1.9.3/Array.html#method-i-3C-3D- 3E用[“d”,“a”,“e”,“c”,“b”],“d”和“a”先比较一下。 然后,由于它下降,都保持在相同的顺序,因为D评估小于a。 然后评估d和e。 “e”移到“d”的位置。 不知道c代码的内部工作原理是不可能知道在哪里移动,但我认为这个过程继续下去,直到所有的元素sorting。 cfunction:
VALUE rb_ary_cmp(VALUE ary1, VALUE ary2) { long len; VALUE v; ary2 = rb_check_array_type(ary2); if (NIL_P(ary2)) return Qnil; if (ary1 == ary2) return INT2FIX(0); v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2); if (v != Qundef) return v; len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2); if (len == 0) return INT2FIX(0); if (len > 0) return INT2FIX(1); return INT2FIX(-1); }