Forum: Ruby Enum#select with max number of items

Posted by masta Blasta (mastablasta)
on 2013-01-24 22:08
My premise is that i have a large array that i'd like to iterate with
select, but
I want up to a maximum (n) number of returns. Something like
Enum#select_first_n_matches.

yes i could do my_arr.select{ blocky }.first(n). Which is a neat
one-liner, but has the performance overhead of iterating through the
entire array.

is there a method that does this already? Anyone have any slick one-line
solutions?

My working solution is:
new_arr = []; matches = 0
my_arr.each do |ele|
  if condition
     new_arr << ele
     matches += 1
     break if matches >= limit
  end
end
Posted by Joel Pearson (virtuoso)
on 2013-01-24 22:14
Not sure about one-liners, but you can replace the matches integer with 
new_arr.count / size / length
Posted by Robert Klemme (robert_k78)
on 2013-01-24 22:57
(Received via mailing list)
On Thu, Jan 24, 2013 at 10:08 PM, masta Blasta <lists@ruby-forum.com> 
wrote:
> solutions?
irb(main):003:0> 1_000_000.times.inject([]) {|a,x| a << x if x.odd?;
break a if a.size >= 10; a}
=> [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
irb(main):004:0> 1_000_000.times.inject([]) {|a,x| x.odd? and a << x
and a.size >= 10 and break a; a}
=> [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

> My working solution is:
> new_arr = []; matches = 0
> my_arr.each do |ele|
>   if condition
>      new_arr << ele
>      matches += 1
>      break if matches >= limit
>   end
> end

You can simplify that

new_arr = []

my_arr.each do |ele|
  if condition
     new_arr << ele
     break if new_arr.size >= limit
  end
end

or

new_arr = []

my_arr.each do |ele|
  condition and
     new_arr << ele and
     new_arr.size >= limit and
     break
end

Kind regards

robert
Posted by Bartosz DziewoƄski (matmarex)
on 2013-01-25 01:26
(Received via mailing list)
You could try out the lazy iterators in Ruby 2.0. The preview has been 
made available recently, and there are articles about this online 
already.
Posted by masta Blasta (mastablasta)
on 2013-01-25 16:49
Robert Klemme wrote in post #1093631:
> or
>
> new_arr = []
>
> my_arr.each do |ele|
>   condition and
>      new_arr << ele and
>      new_arr.size >= limit and
>      break
> end
>

This is clever but is there a specific technical reason for using 'and'. 
To me it makes it harder to read than conventional structure.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.