# .each skipping elements

**URL:** <https://www.ruby-forum.com/t/each-skipping-elements/194836>\
**Category:** Ruby\
**Created:** [September 11, 2010, 10:47pm UTC](https://www.ruby-forum.com/t/each-skipping-elements/194836 "2010-09-11T22:47:10Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cameron1inm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/779978/32.png) [@cameron1inm](https://www.ruby-forum.com/u/cameron1inm)\
**Post date:** [September 11, 2010, 10:47pm UTC](https://www.ruby-forum.com/t/each-skipping-elements/194836/1 "2010-09-11T22:47:10Z")

</div>

I have an array of links from a webpage. I need to clean up the links  
so it only has city links in it. So I do a .each and test for regex.

page.links.each{

if link.text =~ /(Blog|About Us|Status|Help|TOS|Privacy|Are we missing  
an area?)/  
page.links.delete(link)  
end  
end

For some reason the deleting of a link/element causes it to skip the  
next link/element

in the array the last 7 links are

About us  
Blog  
Status  
Help  
TOS  
Privacy  
Are we missing an area?

but after running the .each on the array I still end up with

blog  
help  
privacy

if I run it again

help

lol, so why can’t I do this on just one run threw with .each?  
or why would deleting an element cause it to skip the next one.

I rebuilt it with an ugly while loop with a counter …same problem

---

<div class="post-metadata">

**Author:** ![cameron1inm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/779978/32.png) [@cameron1inm](https://www.ruby-forum.com/u/cameron1inm)\
**Post date:** [September 11, 2010, 10:57pm UTC](https://www.ruby-forum.com/t/each-skipping-elements/194836/2 "2010-09-11T22:57:26Z")

</div>

Hi –

On Sun, 12 Sep 2010, Cameron V. wrote:

> I have an array of links from a webpage. I need to clean up the links  
> so it only has city links in it. So I do a .each and test for regex.
> 
> page.links.each{
> 
> if link.text =~ /(Blog|About Us|Status|Help|TOS|Privacy|Are we missing  
> an area?)/  
> page.links.delete(link)  
> end  
> end

That can’t be the code you’re actually running; it doesn’t assign  
anything to the link variable.

> Privacy  
> help
> 
> lol, so why can’t I do this on just one run threw with .each?  
> or why would deleting an element cause it to skip the next one.
> 
> I rebuilt it with an ugly while loop with a counter …same problem

You’re doing a destructive operation on the array while you’re iterating  
over it, which is going to give odd results. Ruby’s internal counter is  
going to be pointing to the wrong array entry if one of them disappears.

You’re also doing too much work. Try this:

page.links.delete\_if {|link| link =~ /…/ }

David

–  
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally  
Compleat Philadelphia, PA, October 1-2, 2010  
Rubyist [http://www.compleatrubyist.com](http://www.compleatrubyist.com)

---

<div class="post-metadata">

**Author:** ![cameron1inm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/779978/32.png) [@cameron1inm](https://www.ruby-forum.com/u/cameron1inm)\
**Post date:** [September 12, 2010, 1:28am UTC](https://www.ruby-forum.com/t/each-skipping-elements/194836/3 "2010-09-12T01:28:45Z")

</div>

Thanks for the reply and I think I get it now

if we delete element 50  
element 51 gets sloted into 50  
then the pointer moves to 51 never addressing the original 51…ok

page.links.delete\_if{|link| link =~ /(Blog|About  
Us|Status|Help|TOS|Privacy|Are we missing an area?)/  
}

I tried it … it runs… no errors… It loops threw all the link  
elements… but never does any thing… nothing gets deleted

I see how it should work …but it doesn’t

thanks for the help though

---

<div class="post-metadata">

**Author:** ![cameron1inm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/779978/32.png) [@cameron1inm](https://www.ruby-forum.com/u/cameron1inm)\
**Post date:** [September 12, 2010, 4:26am UTC](https://www.ruby-forum.com/t/each-skipping-elements/194836/4 "2010-09-12T04:26:20Z")

</div>

a = [“About us”, “Blog”, “Status”, “Help”, “TOS”, “Privacy”, “Are we  
missing  
an area?”]

a.delete\_if{|link| link =~ /(Blog|About Us|Status|Help|TOS|Privacy|Are  
we  
missing an area?)/ }

p a # return [“About us”]

it works. maybe you need try {|link| link.text=~/…/}

Guten Tag. Linux Ruby

> **[Log in or sign up to view](https://www.facebook.com/gutenlinux)**
>
> See posts, photos and more on Facebook.

Signature powered by  
[http://www.wisestamp.com/email-install?utm\_source=extension&utm\_medium=email&utm\_campaign=footer](http://www.wisestamp.com/email-install?utm_source=extension&utm_medium=email&utm_campaign=footer)  
WiseStamp[http://www.wisestamp.com/email-install?utm\_source=extension&utm\_medium=email&utm\_campaign=footer](http://www.wisestamp.com/email-install?utm_source=extension&utm_medium=email&utm_campaign=footer)

---

<div class="post-metadata">

**Author:** ![cameron1inm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/779978/32.png) [@cameron1inm](https://www.ruby-forum.com/u/cameron1inm)\
**Post date:** [September 13, 2010, 12:48pm UTC](https://www.ruby-forum.com/t/each-skipping-elements/194836/5 "2010-09-13T12:48:28Z")

</div>

On Sun, Sep 12, 2010 at 1:28 AM, Cameron V.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I tried it … it runs… no errors… It loops threw all the link  
> elements… but never does any thing… nothing gets deleted
> 
> I see how it should work …but it doesn’t

Maybe page.links returns a new array every time you call it instead of  
an access to an internal structure. This would mean you modify a copy  
and not the original data. You could verify by doing

3.times do  
puts page.links.object\_id  
end

If you see different object ids chances are that you get a copy and  
are not modifying the original structure.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![cameron1inm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/779978/32.png) [@cameron1inm](https://www.ruby-forum.com/u/cameron1inm)\
**Post date:** [September 12, 2010, 1:58am UTC](https://www.ruby-forum.com/t/each-skipping-elements/194836/6 "2010-09-12T01:58:53Z")

</div>

Hi –

On Sun, 12 Sep 2010, Cameron V. wrote:

> Thanks for the reply and I think I get it now
> 
> if we delete element 50  
> element 51 gets sloted into 50  
> then the pointer moves to 51 never addressing the original 51…ok
> 
> page.links.delete\_if{|link| link =~ /(Blog|About  
> Us|Status|Help|TOS|Privacy|Are we missing an area?)/

(Note that the ? in that regex is a special character and will not match  
an actual question mark. It’s a zero-or-one quantifier, operating on the  
“a” character before it.)

> }
> 
> I tried it … it runs… no errors… It loops threw all the link  
> elements… but never does any thing… nothing gets deleted
> 
> I see how it should work …but it doesn’t

Do you need to make it case insensitive? It definitely works:

$ cat del.rb  
array = [“Keep1”, “Blog”, “Status”, “Keep2”, “TOS”, “Help”, “Keep3”]  
array.delete\_if {|word| word =~ /Blog|Status|TOS|Help/ }  
p array

$ ruby del.rb  
[“Keep1”, “Keep2”, “Keep3”]

so something else must be going on.

David

–  
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally  
Compleat Philadelphia, PA, October 1-2, 2010  
Rubyist [http://www.compleatrubyist.com](http://www.compleatrubyist.com)

---

<div class="post-metadata">

**Author:** ![cameron1inm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/779978/32.png) [@cameron1inm](https://www.ruby-forum.com/u/cameron1inm)\
**Post date:** [September 13, 2010, 7:43pm UTC](https://www.ruby-forum.com/t/each-skipping-elements/194836/7 "2010-09-13T19:43:06Z")

</div>

Yep yep!

needed to add the .text at the end…

Thanks you guys are great…

def city\_update  
city\_name = []  
agent = Mechanize.new  
page = agent.get(‘[craigslist \> sites](http://www.craigslist.org/about/sites)’)  
8.times {page.links.delete\_at(0)}  
page.links.delete\_if{|link|

```
 link.text =~ /(Blog|About Us|Status|Help|TOS|Privacy|Are we missing 

```

an area?)/  
}  
page.links.each{|link|  
city\_name \<\< link.text  
}  
end  
puts city\_update

Thats the whole method… basicly you want to make sure you have a  
current list of availible Craigslist cities… and you want to cut out  
all the non needed links… thanks again
