in reply to Tie::Hash::MultiValue Unique question

Welcome to the Monastery.

I apologize if I misinterpret your question. It's usually a good idea to provide sample data for what you want to do in order to clarify your question. See I know what I mean. Why don't you?.

Fundamental to the hash data structure is a unique key for every entry. Therefore, it is impossible to have a key occur more than once for the hash. If you attempt to store a key-value pair more that once, it will overwrite the old value with the new one, but there will still only be one occurrence of the key.

If, on the other hand, you are trying to check if a value already exists in a hash, that is answered in a faq. Assuming your data is in a hash named %hash, you could check if the value in $value already exists with the code:

my %reverse_hash = reverse %hash; if (not exists $reverse_hash{$value}) { $hash{$key} = $value; }

You could express that much more succinctly, but I expect that would confuse the issue. There are a few other ways I could think of interpreting your question, and so if these explanations do not answer your specific question, please provide some more specificity.

Replies are listed 'Best First'.
Re^2: Tie::Hash::MultiValue Unique question
by elsubliminal (Initiate) on Apr 17, 2009 at 20:56 UTC
    Fellow Monks,

    First of all, Thanks for replying! Much Appreciated!

    Well what I want to do is to insert multiple values per hash
    key. For instance for key , say 1, I want to insert
    {2,3,4,5,6,2,7,8,}, in that order.
    I want to avoid inserting 2 as it has already been inserted.
    The standard push will not do that I guess..
    Thanks!
      You're still not being clear about what you want.

      Here's my take...

      By definition, keys in hashes are always unique. So, if you're after lists of unique things, a hash is what you want. Since you want a unique list inside a hash, you want a hash of hashes. Something like this may do:

      use Data::Dumper; my $first_level_key = 1; my @second_level_keys = (2,3,4,5,6,2,7,8); my %hash; $hash{$first_level_key}{$_}++ for @second_level_keys; print Dumper \%hash;

      You said you wanted to insert "in order". If order is important, you could sort the keys before processing them if they're numeric, as they were in your example. If you do want strictly ordered hashes, there are modules on CPAN that can do this (disclaimer, I haven't used any of them). Just google for them.

      If you want multiple values associated with one hash key, the way this is done in Perl is with a hash of lists. This corresponds to storing an array reference in the value. For an introduction to hashes of lists and other related Perl data structures, see perllol.
        Hmm I see. What I have now is:

        my %edges= ();

        while (<STREAM>) {
        my($node1, $node2) = split;
        push( @{$edges{$node1}}, $node2);

        }
        Now, if the sequence is:
        1,2
        1,3
        1,4
        1,2
        1,5

        2 will be pushed again right? I want to avoid that.
        Thanks!