Project

General

Profile

Feature #8887

Updated by nobu (Nobuyoshi Nakada) almost 11 years ago

How about adding an optional argument, n, for Enumerable#{min,max,min_by,max_by} to 
 return minimum/maximum n elements as an array. 

 Example: 
 * [6, 0, 3, 3, 8, 3, 5, 0, 6].min(4) #=> [0, 0, 3, 3] 
 * [6, 0, 3, 3, 8, 3, 5, 0, 6].max(4) #=> [5, 6, 6, 8] 
 * [6, 0, 3, 3, 8, 3, 5, 0, 6].min_by(4) {|v| (v-5)**2 } #=> [5, 6, 6, 3] 
 * [6, 0, 3, 3, 8, 3, 5, 0, 6].max_by(4) {|v| (v-5)**2 } #=> [3, 8, 0, 0] 

 These methods are similar to sort follows first or last. 

 * e.min(n) is similar to e.sort.first(n) 
 * e.max(n) is similar to e.sort.last(n) 
 * e.min_by(n) {...} is similar to e.sort_by {...}.first(n) 
 * e.max_by(n) {...} is similar to e.sort_by {...}.last(n) 

 However e.min(n), e.max(n), e.min_by(n), e.max_by(n) are 
 less memory consuming and can be faster. 
 They use memory proportional to n, not e. 
 They doesn't sort whole e.  

 I feel their use is not rare. 
 I found several use after searching. 

 [ruby-talk:123508], [ruby-list:40939], [ruby-talk:273980] 
 http://d.hatena.ne.jp/mjh/20101024/1287901875 
 http://stackoverflow.com/questions/11094874/get-top-n-elements-from-ruby-array-of-hash-values 
 http://www.math.kobe-u.ac.jp/~kodama/tips-ruby-sized_pqueue.html 
 https://bitbucket.org/sterlingcamden/topn 

 Also, e.max(n) can be used to implement weighted random sampling. 

 Pavlos S. Efraimidis, Paul G. Spirakis 
 Weighted random sampling with a reservoir 
 Information Processing Letters 
 Volume 97, Issue 5 (16 March 2006) 

 ``` 
   

   % ./ruby -e ' 
   module Enumerable 
     def wsample(n) 
       self.max_by(n) {|v| rand ** (1.0/yield(v)) } 
     end 
   end 
   e = (-20..20).to_a*10000 
   a = e.wsample(20000) {|x| 
     Math.exp(-(x/5.0)**2) # normal distribution 
   } 
   # a is 20000 samples from e. 
   p a.length 
   h = a.group_by {|x| x } 
   -10.upto(10) {|x| puts "*" * (h[x].length/30.0).to_i if h[x] } 
   ' 
   20000 
   * 
   *** 
   ****** 
   *********** 
   ****************** 
   ***************************** 
   ***************************************** 
   **************************************************** 
   *************************************************************** 
   ******************************************************************** 
   *********************************************************************** 
   *********************************************************************** 
   ************************************************************** 
   **************************************************** 
   *************************************** 
   *************************** 
   ****************** 
   *********** 
   ******* 
   *** 
   * 
 ``` 

 Any comments? 

Back