Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

just a quick question here...if i have string i want to match against the key(s) in hash of arrays so that if they are the same i can delete the that key and its corresponding array how would I go about doing that? Also, will deleting the key automatically get rid of its corresponding array. Thanks, this is such a great site, I've learned so much already. Here is what im trying...
while (($key, $value) = each %hash) { print $key, "\n"; <\code> delete $hash{$key}; # This is safe }
it's giving me a syntax error which i believe is because this is a hash of arrays and not a hash. help!!

Edited by castaway - fixed code tags.

Replies are listed 'Best First'.
Re: deletion in hash of array
by davido (Cardinal) on Oct 15, 2003 at 06:34 UTC
    Your <code> tags were messed up a little. The closing tag should have / (forward slash), not backslash.

    Anyway, here is what I think your snippet looked like:

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

    As of Perl 5.6.1 and later it is considered safe to delete the current hash element obtained from each. However, that behavior wasn't always the case (or at least wasn't always documented to be the case). You also must take care not to arbitrarily delete some other element in the hash while iterating over it except for the most recent one returned by each.

    Without seeing the syntax error, I can't say exactly what you're doing wrong. Your code looks ok the way it is.

    delete does exactly what you're implying for it to do: it deletes the hash element identified by key, along with its value, which in your case is a reference to an anonymous array.

    Note, if you're trying to clear out the entire hash, this is much faster:
    %hash = ();
    or
    undef %hash;

    One more observation: You've posted several questions all related to the same general topic. That's great, because most of us enjoy helping. However, it would probably be helpful if you got a Perlmonks account (they're free after all). That would help us to better identify the context of your questions. For me, it was just by recognizing the nature of the question that I knew you were the same person, and that the questions were related, and thus found myself able to provide a more suitable answer. But if you had posted them all from the same user name (other than Anonymous Monk) it would have been easier to make guesses as to the context; I could just look at a list of the last few posts you made. This would help you to get better answers, especially when the questions get more complicated. ...just a thought... ;)

    Update: Camel II (which came out way before 5.6.1) says it's safe to delete keys while using each to iterate over a hash. Apparently it's been safe for awhile. It's still a very good idea to only delete the most recent element that each handed you.


    Dave


    "If I had my life to do over again, I'd be a plumber." -- Albert Einstein
Re: deletion in hash of array
by Roger (Parson) on Oct 15, 2003 at 06:29 UTC
    Use <code> and </code> to quote your code.

    Add use Data::Dumper; to the top of your code, and then add print Dumper(\%hash); before your while loop to investigate what's actually in your hash.

    In my example below, everything worked fine.
    use Data::Dumper; $hash{a} = [ 1, 2, 3 ]; $hash{b} = [ 4, 5, 6 ]; print Dumper(\%hash); while (($key, $value) = each %hash) { print $key, "\n"; delete $hash{$key}; }
    Output -
    $VAR1 = { 'a' => [ 1, 2, 3 ], 'b' => [ 4, 5, 6 ] }; a b
    By the way, what was the syntax error it complained about?