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

Somewhat of a newbie question. Is there a way to test to see if a certain key/value combination exists in a hash WITHOUT looping through it? Perhaps something like the following only that tests for the existance of the key/value pair instead of only the key.

if (exists($file_hash{$file_name})) {
# do something
}else{
# do someting else
}


In other words, I have a new key/value pair and I want to see if that combination already exists in a hash. If it doesn't, I want to add it. If it does, I want to add it to another hash. I really don't want a loop since I will be repeating this process so many times.

Thanks in advance.

Replies are listed 'Best First'.
Re: Testing for key/value match
by Anonymous Monk on May 10, 2002 at 14:41 UTC

    Are you sure that's the behaviour you want? If the hash contains the key but a different value you won't be "adding' your new key/value combination to the hash but overwriting the current value for that key in the hash. If you really wish to test as you suggest, just combine the tests you need.

    if(exists($hash{$key}) && $hash{$key} eq $value) { # combo exists, add $key/$value to different hash } else { # combo doesn't exist, set it here possibly # overwriting previous value for same key. }
Re: Testing for key/value match
by perlplexer (Hermit) on May 10, 2002 at 14:43 UTC
    It seems to me you're misunderstanding how hashes work.
    Keys in a hash are unique. What this means is that you can't have two or more identical keys with different values.
    If you want to test whether a certain key exists and has the value you expect, you can do this
    if (defined $foo{'bar'} and $foo{'bar'} eq 'baz'){ }
    --perlplexer
      If you want to test whether a certain key exists and has the value you expect, you can do this

      if (defined $foo{'bar'} and $foo{'bar'} eq 'baz'){ }
      perhaps you mean exists?

      if (exists $foo{'bar'} and $foo{'bar'} eq 'baz'){ }
      reminder to all: in an array or hash lookup, defined tests for definedness of the value of the array index or hash key, which may not be what you mean. use exists to test whether the array index or hash key is present.

      ~Particle *accelerates*

        No, defined() is what I wanted to say.
        The value may exist but may be undefined, in which case the 'eq' will produce a warning.

        --perlplexer
Re: Testing for key/value match
by cmilfo (Hermit) on May 10, 2002 at 15:08 UTC
    Here is one way.
    my $new_key = 'NEW'; my $new_value = 'Value'; if (exists $file_hash{$new_key} && $file_hash{$new_key} eq $new_value) { # add to another hash, per the comment in your post } else { $file_hash{$new_key} = $new_value; }
    We are testing whether it exists or not to catch the case when $new_value is undefined and $new_key does not exist in the hash. If the $new_value == undef, then no matter what the key is (if it doesn't exist) a true value will be returned because the key in the hash HAS a value of undef.