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
    的对象数组。您可能无法判断object
    bob
    是否大于object
    mike
    (即class
    Person
    没有实现方法
    )。在这种情况下,您需要提供一些代码来解释您希望这些对象按照
    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)