ruby - Sorting multiple values by ascending and descending -
i'm trying sort array of objects based upon different attributes. of attributes sort in ascending order , in descending order. have been able sort ascending or descending have been unable combine two.
here simple class working with:
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
i can instantiate dogs sorted later.
@rover = dog.new("rover", "male") @max = dog.new("max", "male") @fluffy = dog.new("fluffy", "female") @cocoa = dog.new("cocoa", "female")
i can use sort_all_by_gender_then_name method.
dog.sort_all_by_gender_then_name => [@cocoa, @fluffy, @max, @rover]
the array returns includes females first, males, sorted name in ascending order.
but if want have gender descending, , name ascending, males first , sorted name ascending. in case:
=> [@max, @rover, @cocoa, @fluffy]
or, if wanted gender ascending, name descending:
=> [@fluffy, @cocoa, @rover, @max]
when sorting numerical values, can prepend - make sort in reverse. however, have been unable find way strings. or ideas appreciated. thanks.
here's 1 way using .sort
instead of .sort_by
:
dogs = [ { name: "rover", gender: "male" }, { name: "max", gender: "male" }, { name: "fluffy", gender: "female" }, { name: "cocoa", gender: "female" } ] # gender asc, name asc p(dogs.sort |a, b| [a[:gender], a[:name]] <=> [b[:gender], b[:name]] end) # gender desc, name asc p(dogs.sort |a, b| [b[:gender], a[:name]] <=> [a[:gender], b[:name]] end) # gender asc, name desc p(dogs.sort |a, b| [a[:gender], b[:name]] <=> [b[:gender], a[:name]] end)
output:
[{:name=>"cocoa", :gender=>"female"}, {:name=>"fluffy", :gender=>"female"}, {:name=>"max", :gender=>"male"}, {:name=>"rover", :gender=>"male"}] [{:name=>"max", :gender=>"male"}, {:name=>"rover", :gender=>"male"}, {:name=>"cocoa", :gender=>"female"}, {:name=>"fluffy", :gender=>"female"}] [{:name=>"fluffy", :gender=>"female"}, {:name=>"cocoa", :gender=>"female"}, {:name=>"rover", :gender=>"male"}, {:name=>"max", :gender=>"male"}]
basically, doing similar negating numbers (as mentioned in question), swapping property other element if needs sorted in descending order.
Comments
Post a Comment