Ruby - 可枚举对象排序
Varsion

如果有一个类,需要对他的实例化对象进行排序,就需要按照如下方式:

  1. 定义类的比较方法 <=>
  2. 将多个实例对象放入容器
  3. 对这个容器进行排序

关键在于,虽然排序功能是由Enumerable提供的,但是我们自己的类可以不必混合该模块。当然将对象放到集合类型中也有等同于混合了该模块。作为可枚举的集合类型对象有两个可用的排序方法即:sortsort_by

1
[2,4,1,7].sort

当使用数字或者字符串的时候,是十分容易的,放置元素的数组有一种排序机制,整数或者字符串都有着可以排序的方式。

例如需要对一个类的实例对象进行排序:

1
[p1,p2,p3,p4].sort

对于类P的对象来说,如果需要进行排序操作就必须定义飞船运算符<=>p#<=>

1
2
3
def <=> (other_p)
self.price <=> other_p.price
end

定义了该类方法之后,对包含类P的对象进行排序时,会根据price属性来进行排序。

Ruby会应用<=>来测试这些元素,一次两个,以构建足够的信息用于执行完整的排序操作。

可枚举对象排序中的Comparable模块

如果要使在可枚举容器中的对象拥有可枚举能力,关键在于定义<=>,因此无需混合Comparable就可以获得<=>以及排序能力。

  • 如果为一个类定义了<=>,之后这个类的所有实例都可以放到数组或者可枚举对象中进行排序
  • 如果没有定义<=>,仍然可以排序这些对象,只需要将他们放在数组中,并提供一个可以让数组知道如何排列两个对象的代码块。
  • 如果在类中定义了<=>同时也包含了Comparable,之后就可以让数组在使用排序操作时,同时还可以在任意的两个元素对象间执行所有的比较操作。

使用代码块定义排序逻辑

如果对象中并没有定义<=>方法,也可以通过动态的使用代码块来指定对象应该如何排序。即使定义了<=>方法,也可以通过该方法来覆盖已经存在的方法。

1
2
3
[p1,p2,p3,p4].sort do a,b
a.price <=> b.price
end

代码块可以携带两个参数,这样就可以根据需求多次调用代码块以比较两个对象。


  • Post title:Ruby - 可枚举对象排序
  • Post author:Varsion
  • Create time:2020-09-29 17:45:30
  • Post link:https://blog.varsion.cn/post/6fc61016.html
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
Comments