Arrays 当传递一个块时,数组#排序如何工作?
我在理解Arrays 当传递一个块时,数组#排序如何工作?,arrays,ruby,sorting,Arrays,Ruby,Sorting,我在理解array.sort{x,y | block}如何准确工作时遇到了一个问题,因此如何使用它 例如: a=[“d”、“a”、“e”、“c”、“b”] a、 排序#=>[“a”、“b”、“c”、“d”、“e”] a、 排序{| x,y | y x}#=>[“e”,“d”,“c”,“b”,“a”] 在您的示例中 a.sort 相当于 a.sort { |x, y| x <=> y } 及 a.sort{| x,y | yx} 以相反的顺序返回同一数组 为了详细说明Tate
array.sort{x,y | block}
如何准确工作时遇到了一个问题,因此如何使用它
例如:
a=[“d”、“a”、“e”、“c”、“b”]
a、 排序#=>[“a”、“b”、“c”、“d”、“e”]
a、 排序{| x,y | y x}#=>[“e”,“d”,“c”,“b”,“a”]
在您的示例中
a.sort
相当于
a.sort { |x, y| x <=> y }
及
a.sort{| x,y | yx}
以相反的顺序返回同一数组
为了详细说明Tate Johnson添加的内容,如果在任何类上实现比较函数
,您将获得以下结果
Comparable
,该模块将自动为您定义以下方法:between?
,=
,=
,
是一个返回(self.(参数)
)的ruby方法
- -1如果自相矛盾
- 如果self==参数,则为0
- 1如果self>参数
x
和y
是数组项。如果未提供块,sort
函数使用xy
,否则块的结果显示x是否应在y之前
array.sort{|x, y| some_very_complicated_method(x, y) }
这里,如果某个非常复杂的方法(x,y)返回smth,即<0,x被认为<比y,等等…当你有一个整数数组要排序时,sort
方法很容易对元素进行正确排序-首先是较小的数字,最后是较大的数字。这就是使用普通排序
,不带块的时候
但是,在对其他对象进行排序时,可能需要提供一种方法来比较(每个)两个对象。假设您有一个类为Person
的对象数组。您可能无法判断objectbob
是否大于objectmike
(即classPerson
没有实现方法
)。在这种情况下,您需要提供一些代码来解释您希望这些对象按照sort
方法的顺序排序。这就是块形式的作用所在
people.sort{|p1,p2| p1.age <=> p2.age}
people.sort{|p1,p2| p1.children.count <=> p2.children.count}
people.sort{| p1,p2 | p1.age p2.age}
people.sort{p1,p2{p1.children.count p2.children.count}
在所有这些情况下,sort
方法以相同的方式对它们进行排序-使用相同的算法。不同之处在于比较逻辑。一些其他要点:
x
和y
称为块参数。排序方法基本上是这样的:“我给你x和y,你决定x还是y应该排在第一位,我会处理排序方面的无聊事情”
被称为一个
在:
a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"]
a.sort{| x,y | y x}#=>[“e”,“d”,“c”,“b”,“a”]
什么是x和y
x
和y
是排序算法要比较的元素
这对于为自定义类定义哪个元素应该在另一个元素之前很有用
对于基本数据(数字、字符串、日期等),自然顺序是预定义的,但是对于客户元素(即员工),您可以定义在比较中谁先于谁。这一块让你有机会定义它
在yx发生了什么
在那里,他们以降序(值“更高”的元素将优先)而不是自然顺序(xy
)比较元素
方法代表“compareTo”,如果元素相等,则返回0;如果codex/code在codey/code之前,则返回
x
在y
之后,则返回<0。我认为| x,y | yx是按降序一次比较两个元素,如图所示:
用[“d”,“a”,“e”,“c”,“b”],“d”和“a”首先进行比较。然后,由于它是降序的,所以两者的顺序保持相同,因为d的计算结果小于a。然后计算d和e。“e”移动到“d”的位置。如果不知道c代码的内部工作原理,就不可能知道d移动到哪里,但我认为这个过程会一直持续到所有元素都被排序为止。c功能:
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);
}
@OscarRyz的回复澄清了很多关于排序如何工作的问题,尤其是
{ |x, y| y <=> x }
谢谢
Jignesh我认为值得补充的是,
是在Comparable
中定义的一种方法,它与字符串
混合在一起Fixnum
和Bignum
也定义了
。您可以在任何需要排序或比较的类中实现
。我强调了重要的句子。x和y将是数组中的两个元素,由排序算法本身选择。还需要注意的是,你的块可以是复杂的,也可以是深入的。只要返回值准确地反映了您期望操作员的行为,您就可以做任何您需要的事情。因此,如果您想基于布尔值或其他内容进行排序,您可以计算该布尔值并相应地返回-1或1。它很方便。FWIW,
被称为宇宙飞船操作员。老实说,我发现这个答案更有帮助。一张图片能讲一千个单词,一个例子能讲一千行解释。注意:people.sort{p1,p2{p1.age p2.age}
可以重新编写为people.sort_by{p | p.age}
a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"]
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);
}
{ |x, y| y <=> x }
1.9.3dev :001 > a = %w(d e a w f k)
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)