From: knu@... Date: 2017-10-05T10:00:05+00:00 Subject: [ruby-core:83124] [Ruby trunk Feature#12648] `Enumerable#sort_by` with descending option Issue #12648 has been updated by knu (Akinori MUSHA). Something like this can be a solution for sorting with multiple keys with separate ordering directions. ```ruby module Comparable class SortableTuple < Array include Comparable attr_reader :orderings def initialize(orderings) # Adding keyword options like `allow_nil` (`:first`/`:last`) would be great. replace orderings.map { |key, dir| desc = case dir when :desc true when :asc false else raise ArgumentError, "direction must be either :asc or :desc: #{dir.inspect}" end [key, desc] } end def <=>(other) if other.instance_of?(self.class) other.each_with_index { |(b, desc), i| a, = self[i] case cmp = a <=> b when Integer return desc ? -cmp : cmp unless cmp.zero? else return cmp end } end end end def self.[](*args) SortableTuple.new(*args) end end require 'pp' require 'time' pp [ ["banana", Date.parse("2017-10-03")], ["apple", Date.parse("2017-10-03")], ["grape", Date.parse("2017-10-02")], ["melon", Date.parse("2017-10-02")], ["orange", Date.parse("2017-10-01")], ["cherry", Date.parse("2017-10-01")], ].sort_by { |name, date| Comparable[date => :asc, name => :desc] } # [["apple", #], # ["banana", #], # ["grape", #], # ["melon", #], # ["cherry", #], # ["orange", #]] ``` ---------------------------------------- Feature #12648: `Enumerable#sort_by` with descending option https://bugs.ruby-lang.org/issues/12648#change-67068 * Author: sawa (Tsuyoshi Sawada) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- I would like to pass an optional argument to `Enumerable#sort_by` or `Enumerable#sort_by!` to allow descending sort. When the sort key is singular, this could be done by passing a single optinal boolean variable that represents ascending when `false` (default) and descending when `true`: ```ruby [3, 1, 2].sort_by(&:itself) # => [1, 2, 3] [3, 1, 2].sort_by(false, &:itself) # => [1, 2, 3] [3, 1, 2].sort_by(true, &:itself) # => [3, 2, 1] ``` When there are multiple sort keys, corresponding numbers of arguments should be passed: ```ruby [3, 1, 2, 0].sort_by{|e| [e % 2, e]} # => [0, 2, 1, 3] [3, 1, 2, 0].sort_by(false, false){|e| [e % 2, e]} # => [0, 2, 1, 3] [3, 1, 2, 0].sort_by(false, true){|e| [e % 2, e]} # => [2, 0, 3, 1] [3, 1, 2, 0].sort_by(true, false){|e| [e % 2, e]} # => [1, 3, 0, 2] [3, 1, 2, 0].sort_by(true, true){|e| [e % 2, e]} # => [3, 1, 2, 0] ``` -- https://bugs.ruby-lang.org/ Unsubscribe: