Traversing a hash with array refs as keys?

Discussion in 'Perl Misc' started by Bryan, Apr 6, 2007.

  1. Bryan

    Bryan Guest

    Another one...

    I have a structure of key value pairs, where the key is an array, and
    the value is a scalar. I would have preferred to use the scalars as the
    keys, but there may be duplicates, whereas I know the arrays do not.

    In passing in such a structure to a function by reference, how do I
    assign a local var to the array ref inside the hash ref?

    I need to traverse over the thing:

    while ((my $array_ref, my $value) = each(%$hash_ref)) {...}
    Doesnt work, it thinks $array_ref is a string with "REF(0x1e17594)" as a
    value.

    while((my @$array_ref...
    Doesnt work, dereferencing error.

    Im starting to think I am using the wrong structure, but that is really
    the structure of my data: 1-1 key-value relationships, where the array
    is the unique element and therefore the key. Right?

    Dunno. How do I get my array back? I create it like so btw:
    $hashref->{\[@key_array]} = $value;

    Maybe that is messing me up.

    Help?

    B
     
    Bryan, Apr 6, 2007
    #1
    1. Advertising

  2. Bryan wrote:
    > Another one...
    >
    > I have a structure of key value pairs, where the key is an array, and
    > the value is a scalar. I would have preferred to use the scalars as the
    > keys, but there may be duplicates, whereas I know the arrays do not.
    >
    > In passing in such a structure to a function by reference, how do I
    > assign a local var to the array ref inside the hash ref?
    >
    > I need to traverse over the thing:
    >
    > while ((my $array_ref, my $value) = each(%$hash_ref)) {...}
    > Doesnt work, it thinks $array_ref is a string with "REF(0x1e17594)" as a
    > value.


    That is because hash keys *are* strings and whatever you use as a hash key
    will be converted to a string. Once a reference is converted to a string it
    can not be converted back to a reference.


    > while((my @$array_ref...
    > Doesnt work, dereferencing error.
    >
    > Im starting to think I am using the wrong structure, but that is really
    > the structure of my data: 1-1 key-value relationships, where the array
    > is the unique element and therefore the key. Right?
    >
    > Dunno. How do I get my array back? I create it like so btw:
    > $hashref->{\[@key_array]} = $value;


    You are storing a reference to a reference to an array (an anonymous array is
    already a reference.)

    Perhaps either of these modules will do what you want:

    http://search.cpan.org/~fxn/Hash-MultiKey-0.06/
    http://search.cpan.org/~osfameron/Tie-Hash-StructKeyed-0.03/




    John
    --
    Perl isn't a toolbox, but a small machine shop where you can special-order
    certain sorts of tools at low cost and in short order. -- Larry Wall
     
    John W. Krahn, Apr 6, 2007
    #2
    1. Advertising

  3. Bryan wrote:
    > I have a structure of key value pairs, where the key is an array,


    That is impossible. Hash keys can only be strings. Any other scalar value is
    converted into its string representation.

    > the value is a scalar. I would have preferred to use the scalars as
    > the keys, but there may be duplicates, whereas I know the arrays do
    > not.
    > In passing in such a structure to a function by reference, how do I
    > assign a local var to the array ref inside the hash ref?


    So is your key an array or an array reference? Those two things are quite
    different.

    > I need to traverse over the thing:
    >
    > while ((my $array_ref, my $value) = each(%$hash_ref)) {...}
    > Doesnt work, it thinks $array_ref is a string with "REF(0x1e17594)"
    > as a value.


    Correct. As mentioned above keys must be strings.

    > while((my @$array_ref...
    > Doesnt work, dereferencing error.


    Not surprising.

    > Im starting to think I am using the wrong structure,


    Quite possible.

    > but that is
    > really the structure of my data: 1-1 key-value relationships, where
    > the array is the unique element and therefore the key. Right?


    This smells very much like an x-y problem. Do you actually use that hash as
    a hash, i.e. is there really a logical function, that maps your arrays to
    the value? Hashes are ideal for lookups. Do you really get some array from
    somewhere and frequently need to look up the associated value for that array
    in constant time?

    If not then chances are a different data structure would be better suited
    for the job.

    jue
     
    Jürgen Exner, Apr 6, 2007
    #3
  4. Bryan

    darkon Guest

    Jürgen Exner <> wrote:

    > Bryan wrote:
    >> I have a structure of key value pairs, where the key is an
    >> array,

    >
    > That is impossible. Hash keys can only be strings. Any other
    > scalar value is converted into its string representation.
    >

    [snip]
    >
    >> Im starting to think I am using the wrong structure,

    >
    > Quite possible.
    >
    >> but that is
    >> really the structure of my data: 1-1 key-value relationships,
    >> where the array is the unique element and therefore the key.
    >> Right?

    >
    > This smells very much like an x-y problem. Do you actually use
    > that hash as a hash, i.e. is there really a logical function,
    > that maps your arrays to the value? Hashes are ideal for
    > lookups. Do you really get some array from somewhere and
    > frequently need to look up the associated value for that array
    > in constant time?
    >
    > If not then chances are a different data structure would be
    > better suited for the job.


    He could switch to Python and use tuples as the keys. :)

    (Considers.... Nah.)
     
    darkon, Apr 6, 2007
    #4
  5. Bryan

    Mumia W. Guest

    On 04/06/2007 12:32 PM, Bryan wrote:
    > Another one...
    >
    > I have a structure of key value pairs, where the key is an array, and
    > the value is a scalar. [...]


    As the others have said, hash keys must always be scalar strings;
    however, I think there's a module on CPAN that allows you to use
    references as hash keys. It might be Tie::RefHash, but search CPAN
    yourself: http://search.cpan.org/
     
    Mumia W., Apr 7, 2007
    #5
  6. Bryan

    Dr.Ruud Guest

    Bryan schreef:

    > I have a structure of key value pairs, where the key is an array, and
    > the value is a scalar.


    So you have a segmented key. Is the number of segments the same for all?

    You can use

    $HoH{$keypart1}{$keypart2}{$keypart3} = $value;

    (see perldsc)

    or

    $value{$keypart1, $keypart2, $keypart3} = $value;

    (see $; in perlvar)

    --
    Affijn, Ruud

    "Gewoon is een tijger."
     
    Dr.Ruud, Apr 7, 2007
    #6
  7. Bryan

    -berlin.de Guest

    Mumia W. <> wrote in comp.lang.perl.misc:
    > On 04/06/2007 12:32 PM, Bryan wrote:
    > > Another one...
    > >
    > > I have a structure of key value pairs, where the key is an array, and
    > > the value is a scalar. [...]

    >
    > As the others have said, hash keys must always be scalar strings;
    > however, I think there's a module on CPAN that allows you to use
    > references as hash keys. It might be Tie::RefHash, but search CPAN
    > yourself: http://search.cpan.org/


    Tie::RefHash is a standard module.

    Anno
     
    -berlin.de, Apr 11, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Nagle
    Replies:
    3
    Views:
    312
    John Nagle
    Feb 25, 2007
  2. rp
    Replies:
    1
    Views:
    597
    red floyd
    Nov 10, 2011
  3. Tony N.

    Printing an array of hash refs

    Tony N., Sep 22, 2004, in forum: Perl Misc
    Replies:
    11
    Views:
    224
    Tony N.
    Sep 24, 2004
  4. Alfred Z. Newmane
    Replies:
    6
    Views:
    128
    Mark Clements
    May 2, 2005
  5. Replies:
    3
    Views:
    288
    Jürgen Exner
    May 13, 2008
Loading...

Share This Page