Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe in Perl to delete a key from a hash reference when I loop on the same hash? And why?

Tags:

key

hash

perl

I basically want to do this:

foreach my $key (keys $hash_ref) {

    Do stuff with my $key and $hash_ref

    # Delete the key from the hash
    delete $hash_ref->{$key};
}

Is it safe? And why?

like image 525
Mayeu Avatar asked Jun 01 '12 16:06

Mayeu


People also ask

How do I remove a key from a hash in Perl?

undef $hash{$key} and $hash{$key} = undef both make %hash have an entry with key $key and value undef . The delete function is the only way to remove a specific entry from a hash. Once you've deleted a key, it no longer shows up in a keys list or an each iteration, and exists will return false for that key.

How do I loop through a hash in Perl?

Loop over Perl hash values Perl allows to Loop over its Hash values. It means the hash is iterative type and one can iterate over its keys and values using 'for' loop and 'while' loop. In Perl, hash data structure is provided by the keys() function similar to the one present in Python programming language.

What is a hash reference in Perl?

A hash is a basic data type in Perl. It uses keys to access its contents. A hash ref is an abbreviation to a reference to a hash. References are scalars, that is simple values. It is a scalar value that contains essentially, a pointer to the actual hash itself.

How do you maintain a hash order in Perl?

How can I make my hash remember the order I put elements into it? Use the Tie::IxHash from CPAN. use Tie::IxHash; tie my %myhash, 'Tie::IxHash'; for (my $i=0; $i<20; $i++) { $myhash{$i} = 2*$i; } my @keys = keys %myhash; # @keys = (0,1,2,3,...)

How to delete multiple hash elements at once in Perl?

To delete multiple Perl hash elements (key and value) at one time, just pass the Perl delete function the hash keys in an array, like this: delete @hash {key1, key2, ...}; Here's a short Perl script that demonstrates this: Myself, I find this syntax very hard to remember: and that's one reason I have this tutorial out here.

What is a hash in Perl?

This article describes the main functions and syntax rules for for working with hashes in Perl. A hash is an unsorted collection of key value pairs. Within a hash a key is a unique string that references a particular value. A hash can be modified once initialized.

How do I delete an element by hash key?

A Perl hash delete example - Delete an element by hash key. To delete a Perl hash element, use the Perl "delete" function. The general syntax of the Perl delete function looks like this: delete ($hash {$key});

How do I remove a key value pair from a hash?

To remove a key value pair from a hash use the delete function. Delete requires the key of the pair in order to delete it from the hash: To update the value of a pair, simply assign it a new value using the same syntax as to add a new key value pair.


2 Answers

You're not iterating over the hash, you're iterating over the list of keys returned by keys before you even started looping. Keep in mind that

for my $key (keys %$hash_ref) {
   ...
}

is roughly the same as

my @anon = keys %$hash_ref;
for my $key (@anon) {
   ...
}

Deleting from the hash causes no problem whatsoever.


each, on the other, does iterate over a hash. Each time it's called, each returns a different element. Yet, it's still safe to delete the current element!

# Also safe
while (my ($key) = each(%$hash_ref)) {
   ...
   delete $hash_ref->{$key};
   ...
}

If you add or delete a hash's elements while iterating over it, entries may be skipped or duplicated--so don't do that. Exception: It is always safe to delete the item most recently returned by each()

like image 172
ikegami Avatar answered Oct 24 '22 15:10

ikegami


It is safe, because keys %hash provides entire list once, before you start iterating. foreach then continues to work on this pre-generated list, no matter what you change inside actual hash.

It eats up your memory though, because you keep entire list until you've done.

like image 38
Oleg V. Volkov Avatar answered Oct 24 '22 15:10

Oleg V. Volkov