Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Iterating over hash while deleting elements

by LanX (Archbishop)
on Feb 06, 2020 at 16:32 UTC ( #11112495=note: print w/replies, xml ) Need Help??


in reply to Iterating over an hash while removing keys

Eily asked in the CB, here the answer: *

Basically:

  • each has no problem if you delete the current element
  • if you delete other elements, you need to reset the iterator, e.g. with keys
  • then the iterator starts anew with the remaining elements
  • NB if you don't empty the whole hash, you risk an endless loop.

The following demo is always resetting, but doesn't need to.

DB<41> @h{a..c,A..C} = (1..3,11..13) DB<42> x \%h 0 HASH(0x33bf940) 'A' => 11 'B' => 12 'C' => 13 'a' => 1 'b' => 2 'c' => 3 DB<43> while (my ($k,$v) = each %h ) { delete $h{$k}; print "$k,$v\n +"; delete $h{uc($k)} } continue {keys %h } c,3 a,1 B,12 b,2

Question to follow ;-P

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

UPDATE

*) this was a root post which was re-parented to the later question. Partly because it toook eily more than 15 min to ask, but mainly because I liked the idea to defy causality! ;-)

Replies are listed 'Best First'.
Re: Iterating over hash while deleting elements
by Eily (Monsignor) on Feb 06, 2020 at 17:02 UTC

    each has no problem if you delete the current element
    Nice to know but I wouldn't rely on it. I think "don't use each if the hash changes" is an easier rule to follow/understand. And it's safer against possible future changes as well (you might start by only deleting the current key, and then find out you can delete a few more at the same time).

    Question to follow ;-P
    Spooky...

      > Nice to know but I wouldn't rely on it

      It's documented.

      > Exception: It is always safe to delete the item most recently returned by each, so the following code works properly:

      >

      while (my ($key, $value) = each %hash) { print $key, "\n"; delete $hash{$key}; # This is safe }

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        Oh I didn't mean I don't trust perl with that. It's whoever is using perl I have trust issues against ;-)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11112495]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2020-05-31 10:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If programming languages were movie genres, Perl would be:















    Results (173 votes). Check out past polls.

    Notices?