我试图根据不同的属性来排序一组对象.其中一些属性我想按升序排序,一些按降序排列.我已经能够按升序或降序进行分类,但无法将这两者结合起来.
这是我正在使用的简单课程:
- class Dog
- attr_reader :name,:gender
- DOGS = []
- def initialize(name,gender)
- @name = name
- @gender = gender
- DOGS << self
- end
- def self.all
- DOGS
- end
- def self.sort_all_by_gender_then_name
- self.all.sort_by { |d| [d.gender,d.name] }
- end
- end
然后我可以实例化一些狗,以便稍后进行排序.
- @rover = Dog.new("Rover","Male")
- @max = Dog.new("Max","Male")
- @fluffy = Dog.new("Fluffy","Female")
- @cocoa = Dog.new("Cocoa","Female")
然后我可以使用sort_all_by_gender_then_name方法.
- Dog.sort_all_by_gender_then_name
- => [@cocoa,@fluffy,@max,@rover]
但是,如果我想让性别下降,然后将其命名为升序,以便首先是男性,然后按升序排列.在这种情况下:
- => [@max,@rover,@cocoa,@fluffy]
或者,如果我希望通过性别升序,但名称下降:
- => [@fluffy,@max]
解决方法
这是使用.sort而不是.sort_by执行此操作的一种方法:
- dogs = [
- { name: "Rover",gender: "Male" },{ name: "Max",{ name: "Fluffy",gender: "Female" },{ name: "Cocoa",gender: "Female" }
- ]
- # gender asc,name asc
- p(dogs.sort do |a,b|
- [a[:gender],a[:name]] <=> [b[:gender],b[:name]]
- end)
- # gender desc,b|
- [b[:gender],a[:name]] <=> [a[:gender],b[:name]]
- end)
- # gender asc,name desc
- p(dogs.sort do |a,b[:name]] <=> [b[:gender],a[:name]]
- end)
输出:
- [{:name=>"Cocoa",:gender=>"Female"},{:name=>"Fluffy",{:name=>"Max",:gender=>"Male"},{:name=>"Rover",:gender=>"Male"}]
- [{:name=>"Max",{:name=>"Cocoa",:gender=>"Female"}]
- [{:name=>"Fluffy",:gender=>"Male"}]
基本上,这是做一些类似于否定数字(如你在问题中提到的),通过将属性交换到另一个元素,如果需要按降序排序.