https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112013-09-10T23:03:25ZRuby Issue Tracking SystemRuby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=417232013-09-10T23:03:25ZHanmac (Hans Mackowiak)hanmac@gmx.de
<ul></ul><p>hm i am curios in what order <code>max(n)</code> and <code>max_by(n)</code> should return the elements?</p>
<p>like <code>[6, 0, 3, 3, 8, 3, 5, 0, 6].max(4)</code>:<br>
should it return <code>sort.last(n) #> [5, 6, 6, 8]</code><br>
or is that better? <code>[8, 6, 6, 5]</code> because 8 is bigger than 6 ?</p>
<p>PS: <code>min_by(n)</code> and <code>max_by(n)</code> (and maybe <code>sort_by(n)</code>) should maybe implemented different without take, so that it <code>max_by(n)</code> picks only the first <code>n</code> biggest objects without sorting the entire test of the <code>Enumerator</code>?</p>
<p>also about your patch, <code>e.min_by(n).size</code> should respect also <code>n</code> and also <code>enum_size</code>, so it needs to return <code>n</code> when <code>n < as size</code>, and <code>size</code> when <code>n > size</code> (for <code>size != nil</code>)</p> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=417242013-09-10T23:53:17Zakr (Akira Tanaka)akr@fsij.org
<ul></ul><p>2013/9/10 Hanmac (Hans Mackowiak) <a href="mailto:hanmac@gmx.de" class="email">hanmac@gmx.de</a>:</p>
<blockquote>
<p>Issue <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: min(n), max(n), min_by(n), max_by(n) (Closed)" href="https://redmine.ruby-lang.org/issues/8887">#8887</a> has been updated by Hanmac (Hans Mackowiak).</p>
</blockquote>
<blockquote>
<p>hm i am curios in what order max(n) and max_by(n) should return the elements?</p>
<p>like [6, 0, 3, 3, 8, 3, 5, 0, 6].max(4):<br>
should it return sort.last(n) #> [5, 6, 6, 8]<br>
or is that better? [8, 6, 6, 5] because 8 is bigger than 6 ?</p>
</blockquote>
<p>I think sorted order (minimum element first, maximum element last) is intuitive.</p>
<blockquote>
<p>PS: min_by(n) and max_by(n) (and maybe sort_by(n)) should maybe implemented different without take, so that it max_by(n) picks only the first n biggest objects without sorting the entire test of the Enumerator?</p>
</blockquote>
<p>The methods accumelates 4n elements, "sort" them and drop 3n elements<br>
repeatedly.<br>
Also, the "sort" is based on quick sort but doesn't sort a half of<br>
divided elements.</p>
<blockquote>
<p>also about your patch, e.min_by(n).size should respect also n and also enum_size, so it needs to return n when n < as size, and size when n > size (for size != nil)</p>
</blockquote>
<p>As far as I understand, the size method returns number of yield<br>
invocaitons of the enumerator.<br>
The enumerators, e.min_by(n) and e.max_by(n), yields e.size times.<br>
So they returns e.size which is not related to n.</p>
<p>For example, e.reject.size returns e.size as follows.</p>
<p>(1..10).to_a.reject.size #=> 10</p>
<a name="This-doesnt-mean-the-result-array-size-of-reject-method"></a>
<h2 >This doesn't mean the result array size of reject method.<a href="#This-doesnt-mean-the-result-array-size-of-reject-method" class="wiki-anchor">¶</a></h2>
<p>Tanaka Akira</p> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=420622013-09-28T10:54:52Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>File</strong> <i>maxn.pdf</i> added</li></ul><p>slide added</p> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=420632013-09-28T11:09:59Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>File</strong> deleted (<del><i>maxn.pdf</i></del>)</li></ul> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=420642013-09-28T11:10:11Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>File</strong> <a href="/attachments/3980">maxn.pdf</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/3980/maxn.pdf">maxn.pdf</a> added</li></ul><p>slide updated</p> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=451412014-02-14T07:56:10Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>Agreed. I think 2.2 is a good time to add these enhancement.</p>
<p>Matz.</p> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=451432014-02-14T08:44:49Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Category</strong> set to <i>core</i></li><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>akr (Akira Tanaka)</i></li></ul> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=451442014-02-14T08:46:09Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/45144/diff?detail_id=32596">diff</a>)</li></ul> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=451652014-02-14T15:45:24Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>Applied in changeset r44958.</p>
<hr>
<ul>
<li>
<p>enum.c: Enumerable#{min,min_by,max,max_by} extended to take an<br>
optional argument.<br>
(nmin_cmp): New function.<br>
(nmin_block_cmp): Ditto<br>
(nmin_filter): Ditto.<br>
(nmin_i): Ditto.<br>
(nmin_run): Ditto.<br>
(enum_min): Call nmin_run if the optional argument is given.<br>
(nmin_max): Ditto.<br>
(nmin_min_by): Ditto.<br>
(nmin_max_by): Ditto.</p>
</li>
<li>
<p>range.c: Range#{min,max} extended to take an optional argument.<br>
(range_min): Call range_first if the optional argument is given.<br>
(range_max): Call rb_call_super if the optional argument is given.</p>
</li>
</ul>
<p><a href="/issues/8887">[ruby-core:57111]</a> [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: min(n), max(n), min_by(n), max_by(n) (Closed)" href="https://redmine.ruby-lang.org/issues/8887">#8887</a>]</p> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=492362014-10-07T03:20:03ZDavidEGrayson (David Grayson)davidegrayson@gmail.com
<ul></ul><p>Hello. I think the Ruby team should reconsider the ordering of the array returned by <code>max</code> and <code>max_by</code> when the <code>n</code> argument is provided. It makes much more sense to me that it would be sorted in descending order, meaning that the most extreme/special element would be first. For example, I would expect <code>max</code> to behave like this:</p>
<pre><code>[1, 2, 10, 22, 23].max(3) # => [23, 22, 10]
</code></pre>
<p>It seems that min/min_by and max/max_by should be mirrors of each other. For example, I would expect that <code>max_by(n) { |x| x.foo }</code> would be equivalent to <code>min_by(n) { |x| -x.foo }</code>, assuming that <code>foo</code> returns a number.</p>
<p>That leaves us with two choices for the sorting: put the most extreme element first, or put the most extreme element last. I think putting the most extreme element first makes the most sense. Whenever I see any list of top-ranked items, the highest-ranked item is usually first. Here are some examples from the internet: <a href="http://imgur.com/a/MPsJl" class="external">http://imgur.com/a/MPsJl</a></p>
<p>I looked around on StackOverflow.com for Ruby users who might benefit from the new argument to min/min_by/max/max_by. Almost everyone asking a question about it wanted to use something like <code>max_by</code> and wanted to have the most extreme element be listed first:</p>
<ul>
<li><a href="http://stackoverflow.com/questions/19804696" class="external">http://stackoverflow.com/questions/19804696</a></li>
<li><a href="http://stackoverflow.com/questions/11094874" class="external">http://stackoverflow.com/questions/11094874</a></li>
<li><a href="http://stackoverflow.com/questions/9390444" class="external">http://stackoverflow.com/questions/9390444</a></li>
</ul>
<p>However, I should note that in one case, the questioner wanted the order of the original enumerable to be preserved (<a href="http://stackoverflow.com/questions/9459447" class="external">http://stackoverflow.com/questions/9459447</a>), and in another case they didn't specify (<a href="http://stackoverflow.com/questions/12241165" class="external">http://stackoverflow.com/questions/12241165</a>). I didn't find anyone who wanted the most extreme element to be last.</p>
<p>I also looked for similar features in other programming languages. The closest thing I found was Python's <code>heapq.nlargest</code> method, which does return the most extreme element first:</p>
<p><a href="https://docs.python.org/3/library/heapq.html#heapq.nlargest" class="external">https://docs.python.org/3/library/heapq.html#heapq.nlargest</a></p>
<p>In SQL, if you are making a query to get the top 10 rows, I think you must do something like this, which puts the most extreme row first:</p>
<pre><code>select * from players order by score desc limit 10
</code></pre>
<p>In conclusion, I think it is more natural for the <code>max</code> and <code>max_by</code> methods to return arrays with the most extreme element first. I hope the Ruby team will do this before Ruby 2.2.0 is released, since it will be hard to change it later without breaking a lot of people's code.</p>
<p>--David Grayson</p>
<p>P.S. Some other Ruby developers I know here in Las Vegas have agreed with this letter and wanted their names to be included:</p>
<ul>
<li>Jason Arhart</li>
<li>Paul Grayson</li>
</ul> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=492592014-10-07T17:39:32Zjhettich (Jan Hettich)janhettich@earthlink.net
<ul></ul><p>A strong case can be made for returning the elements in their original order. That ordering information is otherwise lost; whereas, the client can always sort the resulting elements in whatever order she wants. This behavior would also be more consistent with other enumerable methods, such as select.</p> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=492632014-10-07T19:15:06Zsawa (Tsuyoshi Sawada)
<ul></ul><p>If descending order is to adopted, a thing that has to be made clear is how to order different objects that are in a tie with respect to the measure in question.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">].</span><span class="nf">max_by</span><span class="p">(</span><span class="mi">6</span><span class="p">){</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span> <span class="o">%</span> <span class="mi">3</span><span class="p">}</span>
</code></pre>
<p>Which of the following should this return?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="p">]</span> <span class="c1"># ascending, stable</span>
<span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">7</span><span class="p">]</span> <span class="c1"># descending, stable</span>
<span class="p">[</span><span class="mi">8</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="c1"># descending, reversed stable</span>
</code></pre> Ruby master - Feature #8887: min(n), max(n), min_by(n), max_by(n)https://redmine.ruby-lang.org/issues/8887?journal_id=494052014-10-13T14:49:08Zakr (Akira Tanaka)akr@fsij.org
<ul></ul><p>David Grayson wrote:</p>
<blockquote>
<p>Hello. I think the Ruby team should reconsider the ordering of the array returned by <code>max</code> and <code>max_by</code> when the <code>n</code> argument is provided. It makes much more sense to me that it would be sorted in descending order, meaning that the most extreme/special element would be first. For example, I would expect <code>max</code> to behave like this:</p>
<pre><code>[1, 2, 10, 22, 23].max(3) # => [23, 22, 10]
</code></pre>
</blockquote>
<p>It seems reasonable.</p>
<p>Other opinions?</p>
<p>Note that the max(n) implementation doesn't maintain the order of original enumerable.<br>
So it is difficult to preserve the original order or stablility.</p>