# Looping through array, deleting elements

**URL:** <https://www.ruby-forum.com/t/looping-through-array-deleting-elements/88199>\
**Category:** Ruby\
**Created:** [March 8, 2007, 9:46pm UTC](https://www.ruby-forum.com/t/looping-through-array-deleting-elements/88199 "2007-03-08T21:46:04Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dkmd\_nielsen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/958977/32.png) [@dkmd\_nielsen](https://www.ruby-forum.com/u/dkmd_nielsen)\
**Post date:** [March 8, 2007, 9:46pm UTC](https://www.ruby-forum.com/t/looping-through-array-deleting-elements/88199/1 "2007-03-08T21:46:04Z")

</div>

My idea of looping through an array, interrogating elements that are  
of class instruction, and deleting the element does not appear to work  
as I thought. I think I know why. What is the best solution?

block.each {|i| ab.delete(i) if i.parm == “FOO”}

where block is a series of elements of class instruction(i). Class  
instruction has two attributes, parm and arg. If the instruction parm  
is FOO, then delete the instruction object from the array and keep  
looping. Half of what should be deleted actually get’s deleted. I  
think the reason is: the loop is looking at element x foo, element x  
foo get’s deleted, the array is shifted left, array pointer has not  
changed but is now referencing element y foo, loop advances the array  
pointer, and now array pointer is pointing at element z foo.

If what I think is correct, what is the best solution? Do I set the  
current element to nil, then compact the array after the loop? Do I  
delete the instruction and then do a redo? Or is there a better  
solution than those?

Thanks,  
dvn

---

<div class="post-metadata">

**Author:** ![dkmd\_nielsen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/958977/32.png) [@dkmd\_nielsen](https://www.ruby-forum.com/u/dkmd_nielsen)\
**Post date:** [March 8, 2007, 9:49pm UTC](https://www.ruby-forum.com/t/looping-through-array-deleting-elements/88199/2 "2007-03-08T21:49:45Z")

</div>

dkmd\_nielsen wrote:

> My idea of looping through an array, interrogating elements that are  
> of class instruction, and deleting the element does not appear to work  
> as I thought. I think I know why. What is the best solution?

What about the Array#delete\_if method?

---

<div class="post-metadata">

**Author:** ![dkmd\_nielsen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/958977/32.png) [@dkmd\_nielsen](https://www.ruby-forum.com/u/dkmd_nielsen)\
**Post date:** [March 8, 2007, 9:51pm UTC](https://www.ruby-forum.com/t/looping-through-array-deleting-elements/88199/3 "2007-03-08T21:51:05Z")

</div>

On 08/03/07, dkmd\_nielsen [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> think the reason is: the loop is looking at element x foo, element x  
> dvn  
> This sounds like it would be a lot easier with Array#reject or  
> Array#select.

---

<div class="post-metadata">

**Author:** ![dkmd\_nielsen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/958977/32.png) [@dkmd\_nielsen](https://www.ruby-forum.com/u/dkmd_nielsen)\
**Post date:** [March 8, 2007, 9:53pm UTC](https://www.ruby-forum.com/t/looping-through-array-deleting-elements/88199/4 "2007-03-08T21:53:05Z")

</div>

Alle giovedì 8 marzo 2007, dkmd\_nielsen ha scritto:

> think the reason is: the loop is looking at element x foo, element x  
> dvn  
> I’m not sure I understand your code (what is that ab in the each block?)  
> At  
> any rate, there’s method which directly deletes the elements of an array  
> which satisfy a given condition: Array#delete\_if:

a=[1,2,3,4,5,6]  
a.delete\_if{|i| i \> 3}  
=\> [1,2,3]

This method passes each element of the array to the block, then deletes  
it if  
the block returns true.

Stefano

---

<div class="post-metadata">

**Author:** ![dkmd\_nielsen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/958977/32.png) [@dkmd\_nielsen](https://www.ruby-forum.com/u/dkmd_nielsen)\
**Post date:** [March 8, 2007, 10:04pm UTC](https://www.ruby-forum.com/t/looping-through-array-deleting-elements/88199/5 "2007-03-08T22:04:07Z")

</div>

On 3/8/07, dkmd\_nielsen [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> My idea of looping through an array, interrogating elements that are  
> of class instruction, and deleting the element does not appear to work  
> as I thought. I think I know why. What is the best solution?
> 
> block.each {|i| ab.delete(i) if i.parm == “FOO”}

Not a good idea! You are modifying the array as you iterate over it  
– this will cause some unexpected behavior:

ary = [1,2,3,4]  
ary.each {|x| ary.delete(x) if x \> 2}

p ary #=\> [1, 2, 4]

oops!

> where block is a series of elements of class instruction(i). Class  
> instruction has two attributes, parm and arg. If the instruction parm  
> is FOO, then delete the instruction object from the array and keep  
> looping. Half of what should be deleted actually get’s deleted. I  
> think the reason is: the loop is looking at element x foo, element x  
> foo get’s deleted, the array is shifted left, array pointer has not  
> changed but is now referencing element y foo, loop advances the array  
> pointer, and now array pointer is pointing at element z foo.

You are correct. What happens is that we delete the number 3 from the  
array and this compacts the array – 4 shifts into the position where  
3 just was. Now the “each” method moves the index to the next position  
thereby skipping the number 4.

> If what I think is correct, what is the best solution? Do I set the  
> current element to nil, then compact the array after the loop? Do I  
> delete the instruction and then do a redo? Or is there a better  
> solution than those?

Use the delete\_if method on the array.

ary.delete\_if {|x| x \> 2}

p ary #=\> [1,2]

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![dkmd\_nielsen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/958977/32.png) [@dkmd\_nielsen](https://www.ruby-forum.com/u/dkmd_nielsen)\
**Post date:** [March 8, 2007, 10:45pm UTC](https://www.ruby-forum.com/t/looping-through-array-deleting-elements/88199/6 "2007-03-08T22:45:18Z")

</div>

On Mar 8, 3:02 pm, “Tim P.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > looping. Half of what should be deleted actually get’s deleted. I  
> > If what I think is correct, what is the best solution? Do I set the  
> > Blessings,  
> > TwP

There are a couple of dumb things I have done. First, I had omitted  
that block is an object, not of class array. So its each method is  
iterating through an array internal to it. Nice little detail to  
omit. Duh. Second, there is something called “retry”. I was aware  
of break, next, and redo, but I was unware of “retry.” It worked  
great.

I looked at the delete\_if. What I could do with that is create a  
delete\_if method in the class block that implements delete\_if. In the  
long run, I think that is the best thing to do.

Thanks for everything. One always finds the answer on his/her own  
shortly after asking for help.

dvn
