Basic ruby looping question

I'm trying to do something regarding looping through an array, but only
with elements I need. I'm not sure exactly how to go about it to make it
the most efficient. Is there basically a way to do something like:

for row in @large_row_array WHERE row.element == "something"
... some some stuff
end

What would be the best way to accomplish the above? Would I use perhaps
some nested loops? Thanks for any help, I'm just getting started with
Ruby along with more indepth programming in general and I'm loving it.

···

--
Posted via http://www.ruby-forum.com/.

You can use Array#select to get the values you want:

  for row in @large_row_array.select{ |row| row.element == "something" }
    something
  end

···

On 5/27/06, Marston A. <marston@marstononline.com> wrote:

I'm trying to do something regarding looping through an array, but only
with elements I need. I'm not sure exactly how to go about it to make it
the most efficient. Is there basically a way to do something like:

for row in @large_row_array WHERE row.element == "something"
... some some stuff
end

What would be the best way to accomplish the above? Would I use perhaps
some nested loops? Thanks for any help, I'm just getting started with
Ruby along with more indepth programming in general and I'm loving it.

--
Posted via http://www.ruby-forum.com/\.

Marston A. wrote:

I'm trying to do something regarding looping through an array, but only
with elements I need. I'm not sure exactly how to go about it to make it
the most efficient. Is there basically a way to do something like:

for row in @large_row_array WHERE row.element == "something"
... some some stuff
end

What would be the best way to accomplish the above? Would I use perhaps
some nested loops? Thanks for any help, I'm just getting started with
Ruby along with more indepth programming in general and I'm loving it.

I'm not sure if it's always more efficient, but you can use grep in some
cases:

irb(main):003:0> ENV.keys.grep(/ruby/i) {|key| p key}
"RUBYOPT"
"RUBYLIB"

This is more or less the same as

irb(main):004:0> ENV.keys.each {|key| if /ruby/i === key then p key end}
"RUBYOPT"
"RUBYLIB"

(The return values are quite different though.)

So as long as you are working with tests that can be expressed using
#===, you can use #grep. It's compact, and at least sometimes more
efficient.

require 'benchmark'

a = (0..1_000_000).map {|i| i.to_s}

def foo s
end

Benchmark.bmbm do |b|
  b.report("grep") do
    a.grep(/^10*$/) {|s| foo s}
  end

  b.report("each-if") do
    a.each {|s| if /^10*$/ === s then foo s end }
  end

  b.report("select-each") do
    a.select {|s| /^10*$/ === s}.each {|s| foo s}
  end
end

__END__

Rehearsal -----------------------------------------------
grep 0.490000 0.000000 0.490000 ( 0.492667)
each-if 0.640000 0.000000 0.640000 ( 0.638102)
select-each 0.760000 0.000000 0.760000 ( 0.758676)
-------------------------------------- total: 1.890000sec

                  user system total real
grep 0.490000 0.000000 0.490000 ( 0.487539)
each-if 0.640000 0.000000 0.640000 ( 0.639301)
select-each 0.620000 0.010000 0.630000 ( 0.621152)

···

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Marston A. wrote:

for row in @large_row_array WHERE row.element == "something"
... some some stuff
end

   @array.select{|row| row.element == "something"}.each do |row|
     ... some stuff
   end

Cheers,
Daniel

Marston A. wrote:

I'm trying to do something regarding looping through an array, but only
with elements I need. I'm not sure exactly how to go about it to make it
the most efficient. Is there basically a way to do something like:

for row in @large_row_array WHERE row.element == "something"
... some some stuff
end

You can use array.select as the others have mentioned, or you can use
next like this:

for row in @large_row_array
  next unless row.element == "something"
  ... some some stuff
end

That might be a bit quicker over large data sets, too -- select will
loop through your data before the for loop.

Cheers,
Dave

Joel VanderWerf wrote:

Marston A. wrote:

...

for row in @large_row_array WHERE row.element == "something"
... some some stuff
end

...

So as long as you are working with tests that can be expressed using
#===, you can use #grep.

In your case, grep may not be so useful after all. You would have to
define an object whose #=== method performs the row.element ==
"something" test.

require 'benchmark'

tester = Object.new
def tester.===(row)
  row.element == 987654
end

class Row
  attr_accessor :element
end

rows = (0..1_000_000).map {|i| r = Row.new; r.element = i; r}

Benchmark.bmbm do |b|
  b.report("grep") do
    rows.grep(tester) {|row|}
  end

  b.report("each-if") do
    rows.each {|row| if row.element == 987654 then nil end }
  end

  b.report("select-each") do
    rows.select {|row| row.element == 987654}.each {|row|}
  end
end

__END__

Rehearsal -----------------------------------------------
grep 0.720000 0.000000 0.720000 ( 0.725553)
each-if 0.590000 0.000000 0.590000 ( 0.587160)
select-each 0.770000 0.000000 0.770000 ( 0.768704)
-------------------------------------- total: 2.080000sec

                  user system total real
grep 0.730000 0.000000 0.730000 ( 0.735809)
each-if 0.590000 0.000000 0.590000 ( 0.587350)
select-each 0.570000 0.000000 0.570000 ( 0.564276)

···

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Thanks everyone, I this was exactly what I needed.

···

--
Posted via http://www.ruby-forum.com/.