# Exit a block

**URL:** <https://www.ruby-forum.com/t/exit-a-block/86207>\
**Category:** Ruby\
**Created:** [February 20, 2007, 5:15pm UTC](https://www.ruby-forum.com/t/exit-a-block/86207 "2007-02-20T17:15:01Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jimb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f4b2a3/32.png) [@jimb](https://www.ruby-forum.com/u/jimb)\
**Post date:** [February 20, 2007, 5:15pm UTC](https://www.ruby-forum.com/t/exit-a-block/86207/1 "2007-02-20T17:15:01Z")

</div>

I need to step through a byte array untill I find a certain value, then  
I need to check that the next item in the array is a certain value, it  
is the first index that I require.

So two questions:

1. How would you do it? (my ruby sucks, so interested in seeing decent  
code)

2. If your in a block  
i.e.  
myarray.each\_with\_index{|a,i| if(a == 666):return i end}  
then how can you exit the block and return a value without continuing  
through the loop.

Thanks,  
Jim.

---

<div class="post-metadata">

**Author:** ![jimb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f4b2a3/32.png) [@jimb](https://www.ruby-forum.com/u/jimb)\
**Post date:** [February 20, 2007, 5:25pm UTC](https://www.ruby-forum.com/t/exit-a-block/86207/2 "2007-02-20T17:25:23Z")

</div>

On 20.02.2007 17:15, Jim B. wrote:

> ```
> i.e.
> myarray.each_with_index{|a,i| if(a == 666):return i end}
> 
> ```
> 
> then how can you exit the block and return a value without continuing  
> through the loop.

You can use break or if inside a method return will work as well. I.e.  
you could do

# straightforward simple solution

def find\_my\_index(arr)  
for i in 0 … arr.length-1  
return i if arr[i] == 66 and arr[i+1] == 55  
end

# not found

nil  
end

Of course there is a ton of other possible solutions… I find break  
often not as useful as return because it has the drawback that  
Array#each will always return the array item itself if you do not break  
in between. That way you have to check the return value of #each which  
I find inelegant.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![jimb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f4b2a3/32.png) [@jimb](https://www.ruby-forum.com/u/jimb)\
**Post date:** [February 20, 2007, 5:44pm UTC](https://www.ruby-forum.com/t/exit-a-block/86207/3 "2007-02-20T17:44:28Z")

</div>

Thanks for your help, sometimes best just to program an old fashion for  
loop 😉

Thanks,  
Jim.

---

<div class="post-metadata">

**Author:** ![jimb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f4b2a3/32.png) [@jimb](https://www.ruby-forum.com/u/jimb)\
**Post date:** [February 20, 2007, 6:53pm UTC](https://www.ruby-forum.com/t/exit-a-block/86207/4 "2007-02-20T18:53:29Z")

</div>

On 2/20/07, Jim B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thanks for your help, sometimes best just to program an old fashion for  
> loop 😉

…except that:

for a in b  
return a if a \> 5  
end

…is the same as:

b.each { |a| return a if a \> 5 }

(Except in matters of scope.)

-austin

---

<div class="post-metadata">

**Author:** ![jimb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f4b2a3/32.png) [@jimb](https://www.ruby-forum.com/u/jimb)\
**Post date:** [February 20, 2007, 9:59pm UTC](https://www.ruby-forum.com/t/exit-a-block/86207/5 "2007-02-20T21:59:03Z")

</div>

If it can be compromised to have another variable,  
its more like the ruby way …

lets say myarray=[1,2,3,666,7]

myarray.each\_with\_index{|a,i| index = i and break if a == 666 }

index # =\> 3

---

<div class="post-metadata">

**Author:** ![jimb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f4b2a3/32.png) [@jimb](https://www.ruby-forum.com/u/jimb)\
**Post date:** [February 20, 2007, 11:02pm UTC](https://www.ruby-forum.com/t/exit-a-block/86207/6 "2007-02-20T23:02:12Z")

</div>

On 2/20/07, Jim B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thanks for your help, sometimes best just to program an old fashion for  
> loop 😉

Nahh, more abstraction is a good thing =)

```
require 'enumerator'
class Array
  def find_my_index(x,y)
    to_enum(:each_with_index).each_cons(2) {|(a,i),(b,_)|
      return i if a == x && b == y
    }
    nil
  end
end

```

And then it’s just:

```
ary = [43,21,56,12,93,12]

puts ary.find_my_index(12,93) # => 3
puts ary.find_my_index(93,12) # => 4
puts ary.find_my_index(56,100) # => nil

```

---

<div class="post-metadata">

**Author:** ![jimb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/f4b2a3/32.png) [@jimb](https://www.ruby-forum.com/u/jimb)\
**Post date:** [February 21, 2007, 3:42am UTC](https://www.ruby-forum.com/t/exit-a-block/86207/7 "2007-02-21T03:42:54Z")

</div>

Lou S. wrote:

> ```
> require 'enumerator'
> class Array
> def find_my_index(x,y)
> to_enum(:each_with_index).each_cons(2) {|(a,i),(b,_)|
> return i if a == x && b == y
> }
> nil
> end
> end
> 
> ```

I prefer to leave the actual searching to the Array class. Who knows, it  
might cache a partial-order tree representation of the array and use  
some micro-optimized search algorithm that performs O(log n) on average?

Here is a short one-line solution in that spirit:

class Array  
def find\_my\_index x, y  
i = index(x) and self[i+1] == y and i  
end  
end

Here is a more human readable version, if you don’t mind two extra  
lines:

class Array  
def find\_my\_index x, y  
if i = index(x) and self[i+1] == y  
i  
end  
end  
end
