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

arrgh, for some reason, i cant seem to dereference the array that is the key of a hash in my program. Here is an example of the problem:
@a=qw\ 2 4 7 6 4\; $hash{[@a]} = "jello"; foreach $i (keys %hash) { print @$i; }
This produces no output, however if you dont dereference $i, it does produce the address of the array, what is going on?

Replies are listed 'Best First'.
Re: array reference as hash key
by blakem (Monsignor) on Feb 26, 2002 at 00:41 UTC
    As stated above, you can't do this directly... However, the Tie::Refhash module, might be just what you're looking for.

    -Blake

(Ovid) Re: array reference as hash key
by Ovid (Cardinal) on Feb 26, 2002 at 00:47 UTC

    Why would you want to use an array reference as a hash key? The point of a hash is to have a key to quickly and easily access data in a non-sequential manner. Using an array reference doesn't seem to facilitate that (of course, I'm not sure what you're trying to accomplish). If you want, you can take an array's reference and by using the stringified value as a hash key, you can get a one-to-one mapping, but this really strikes me as something to be avoided without good reason.

    So, the question is, what problem are you trying to solve?

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      well, i was just messing around with psuedo genetic programming, and had 30 arrays of the possible characters in a larger, and needed a rating for each one, so i decided i would either have the array of 30 possible character arrays, and another array that contained the rating for each item, i.e $rating[0] would be the rating for $possiblechar[0] (which is an array). I thought i could avoid the problem of making sure they were sync-ed by having a hash with the reference to the each array of possible characters be the key, and the pair for that key be the rating. That way there wouldn't be any problem making sure they were sync-ed or dealing with more then one data structure. Maybe not the smartest way outside of the fact that perl doesnt allow you to use array references as hash keys
        If you are only concerned with what array belongs to a particular rating (i.e., you supply the rating and want to know what sequence it is), then just reverse your logic: make the rating the key and the array the value.

        If you are also concerned with what rating belongs to a particular sequence however (i.e., you supply the sequence and want to know it's rating), you will have to rely on a more complex data structure than an array or a hash. One example is an array reference that contains array references that contain the rating as their first element, and the sequence (as yet another array reference) as the second element:

        my $ref = [ [2, [qw(g a t a c a)]], [3, [qw(a t a c a g)]], [1, [qw(t a c a g a)]], ];
        And a nasty one liner to print them out (one per line) ordered by their rating:
        print map {join('',@{$_->[1]})."\n"} sort {$a->[0] <=> $b->[0]} @$ref;

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)
        

        As I pointed out in an earlier message in this thread, you could use the references as keys, provided you have a secondary way of reverting the keys back into valid references.

        However, I think you would be better served by designing a more appropriate data structure for this task. Have a closer look at the Perl Data Structures page, or the Perl Data Structures Cookbook page.

        --rjray

      I know this is an old thread, but I thought I'd answer the question (why would you want to use a reference as a hash key) anyway.

      In my case I want to use a hash reference as a key to another hash so I can link two different hashes together w/o duplicating the keys repeatedly in the other hash. I have a doubly linked hash (a->b and b<-a) and I also have large keys for each hash so I don't want to duplicate them repeatedly.

      Consider the case of processing student enrollment data. In one hash I want to link each occurrence of a student (the key) to the list of classes he took (the value: an anonymous hash w/ the class name as the key and the grade as the value). I also want to link the opposite way in another hash where the class name is the key and the value is an anonymous hash with the student name as key and the grade as the value. Since all my keys are large text strings (student name or class name), I would prefer to store a reference to the opposing hash rather than the key itself.

Re: array reference as hash key
by cyocum (Curate) on Feb 26, 2002 at 00:37 UTC
    Unfortunetly, you cannot use a reference as a hash key. Look in "References Don't Work as Hash Keys" in the camel book (3rd ed.) page 265.

      You can use a reference as a hash key, it just is not useful to do so. The reference will be stringified, and cannot be converted back to the data it originally referred to. The Perl References manual page covers this towards the end, under the appropriate heading of "WARNING".

      The exact same reference will always stringify the same way, and in that sense it could be used with effect as a hash key. However, you would still have to have another means by which to map the stringified key back to the original ref. The section above gives one example of how to do this.

      --rjray