# Basic ruby looping question

**URL:** <https://www.ruby-forum.com/t/basic-ruby-looping-question/61808>\
**Category:** Ruby\
**Created:** [May 27, 2006, 8:49pm UTC](https://www.ruby-forum.com/t/basic-ruby-looping-question/61808 "2006-05-27T20:49:46Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![marstoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@marstoni](https://www.ruby-forum.com/u/marstoni)\
**Post date:** [May 27, 2006, 8:49pm UTC](https://www.ruby-forum.com/t/basic-ruby-looping-question/61808/1 "2006-05-27T20:49:46Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![marstoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@marstoni](https://www.ruby-forum.com/u/marstoni)\
**Post date:** [May 27, 2006, 9:01pm UTC](https://www.ruby-forum.com/t/basic-ruby-looping-question/61808/2 "2006-05-27T21:01:19Z")

</div>

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

for row in @large\_row\_array.select{ |row| row.element == “something” }  
something  
end

---

<div class="post-metadata">

**Author:** ![marstoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@marstoni](https://www.ruby-forum.com/u/marstoni)\
**Post date:** [May 27, 2006, 9:19pm UTC](https://www.ruby-forum.com/t/basic-ruby-looping-question/61808/3 "2006-05-27T21:19:51Z")

</div>

Marston A. wrote:

> 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)

---

<div class="post-metadata">

**Author:** ![marstoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@marstoni](https://www.ruby-forum.com/u/marstoni)\
**Post date:** [May 27, 2006, 10:11pm UTC](https://www.ruby-forum.com/t/basic-ruby-looping-question/61808/4 "2006-05-27T22:11:26Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![marstoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@marstoni](https://www.ruby-forum.com/u/marstoni)\
**Post date:** [May 27, 2006, 9:32pm UTC](https://www.ruby-forum.com/t/basic-ruby-looping-question/61808/5 "2006-05-27T21:32:01Z")

</div>

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)

---

<div class="post-metadata">

**Author:** ![marstoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@marstoni](https://www.ruby-forum.com/u/marstoni)\
**Post date:** [May 27, 2006, 10:18pm UTC](https://www.ruby-forum.com/t/basic-ruby-looping-question/61808/6 "2006-05-27T22:18:54Z")

</div>

Thanks everyone, I this was exactly what I needed.

---

<div class="post-metadata">

**Author:** ![marstoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@marstoni](https://www.ruby-forum.com/u/marstoni)\
**Post date:** [May 28, 2006, 6:19am UTC](https://www.ruby-forum.com/t/basic-ruby-looping-question/61808/7 "2006-05-28T06:19:23Z")

</div>

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
