<p>I'd really like to handle this without monkey-patching but I haven't been able to find another option yet.</p>

<p>I have an array (in Ruby) that I need to sort by multiple conditions.  I know how to use the sort method and I've used the trick on sorting using an array of options to sort by multiple conditions.  However, in this case I need the first condition to sort ascending and the second to sort descending.  For example:</p>

<pre><code>ordered_list = [[1, 2], [1, 1], [2, 1]]
</code></pre>

<p>Any suggestions?</p>

<p>Edit:  Just realized I should mention that I can't easily compare the first and second values (I'm actually working with object attributes here).  So for a simple example it's more like:</p>

<pre><code>ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
</code></pre>

[{'answer_id': 73090, 'author': 'Brian Phillips', 'author_id': 7230, 'author_profile': 'https://Stackoverflow.com/users/7230', 'pm_score': 6, 'selected': True, 'text': '<p>How about:</p>\n\n<pre>\n<code>\nordered_list = [[1, "b"], [1, "a"], [2, "a"]]\nordered_list.sort! do |a,b|\n  [a[0],b[1]] &lt;=&gt; [b[0], a[1]]\nend\n</code>\n</pre>\n'}, {'answer_id': 73496, 'author': 'glenn mcdonald', 'author_id': 7919, 'author_profile': 'https://Stackoverflow.com/users/7919', 'pm_score': 2, 'selected': False, 'text': '<p>I had this same basic problem, and solved it by adding this:</p>\n\n<pre><code>class Inverter\n  attr_reader :o\n\n  def initialize(o)\n    @o = o\n  end\n\n  def &lt;=&gt;(other)\n    if @o.is &amp;&amp; other.o.is\n      -(@o &lt;=&gt; other.o)\n    else\n      @o &lt;=&gt; other.o\n    end\n  end\nend\n</code></pre>\n\n<p>This is a wrapper that simply inverts the &lt;=> function, which then allows you to do things like this:</p>\n\n<pre><code>your_objects.sort_by {|y| [y.prop1,Inverter.new(y.prop2)]}\n</code></pre>\n'}, {'answer_id': 76148, 'author': 'mislav', 'author_id': 11687, 'author_profile': 'https://Stackoverflow.com/users/11687', 'pm_score': 2, 'selected': False, 'text': '<p><code>Enumerable#multisort</code> is a generic solution that can be applied to arrays of <strong>any size</strong>, not just those with 2 items. Arguments are booleans that indicate whether a specific field should be sorted ascending or descending (usage below):</p>\n\n<pre><code>items = [\n  [3, "Britney"],\n  [1, "Corin"],\n  [2, "Cody"],\n  [5, "Adam"],\n  [1, "Sally"],\n  [2, "Zack"],\n  [5, "Betty"]\n]\n\nmodule Enumerable\n  def multisort(*args)\n    sort do |a, b|\n      i, res = -1, 0\n      res = a[i] &lt;=&gt; b[i] until !res.zero? or (i+=1) == a.size\n      args[i] == false ? -res : res\n    end\n  end\nend\n\nitems.multisort(true, false)\n# =&gt; [[1, "Sally"], [1, "Corin"], [2, "Zack"], [2, "Cody"], [3, "Britney"], [5, "Betty"], [5, "Adam"]]\nitems.multisort(false, true)\n# =&gt; [[5, "Adam"], [5, "Betty"], [3, "Britney"], [2, "Cody"], [2, "Zack"], [1, "Corin"], [1, "Sally"]]\n</code></pre>\n'}, {'answer_id': 3275140, 'author': 'Alex Fortuna', 'author_id': 243424, 'author_profile': 'https://Stackoverflow.com/users/243424', 'pm_score': 2, 'selected': False, 'text': '<p>I\'ve been using Glenn\'s recipe for quite a while now. Tired of copying code from project to project over and over again, I\'ve decided to make it a gem:</p>\n\n<p><a href="http://github.com/dadooda/invert" rel="nofollow noreferrer">http://github.com/dadooda/invert</a></p>\n'}, {'answer_id': 11320778, 'author': 'TwoByteHero', 'author_id': 1311787, 'author_profile': 'https://Stackoverflow.com/users/1311787', 'pm_score': 3, 'selected': False, 'text': "<p>I was having a nightmare of a time trying to figure out how to reverse sort a specific attribute but normally sort the other two.  Just a note about the sorting for those that come along after this and are confused by the |a,b| block syntax.  You cannot use the <code>{|a,b| a.blah &lt;=&gt; b.blah}</code> block style with <code>sort_by!</code> or <code>sort_by</code>.  It must be used with <code>sort!</code> or <code>sort</code>.  Also, as indicated previously by the other posters swap <code>a</code> and <code>b</code> across the comparison operator <code>&lt;=&gt;</code> to reverse the sort order.  Like this:</p>\n\n<p>To sort by blah and craw normally, but sort by bleu in reverse order do this:</p>\n\n<pre><code>something.sort!{|a,b| [a.blah, b.bleu, a.craw] &lt;=&gt; [b.blah, a.bleu, b.craw]}\n</code></pre>\n\n<p>It is also possible to use the <code>-</code> sign with <code>sort_by</code> or <code>sort_by!</code> to do a reverse sort on numerals (as far as I am aware it only works on numbers so don't try it with strings as it just errors and kills the page).  </p>\n\n<p>Assume <code>a.craw</code> is an integer.  For example:</p>\n\n<pre><code>something.sort_by!{|a| [a.blah, -a.craw, a.bleu]}\n</code></pre>\n"}]
['https://Stackoverflow.com/questions/73032', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3230/']