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

I have this really annoying problem that I can't seem to figure out... I need to create a hash that contains two sets of arrays embedded. Editting the array in the hash would look like this:

$db{'key1'}{'key2'}[0][0] = "one_value"; $db{'key1'}{'key2'}[0][1] = "two_value"; $db{'key1'}{'key2'}[1][0] = "three_value"; $db{'key1'}{'key2'}[1][1] = "four_value"; $db{'key1'}{'key2'}[2][0] = "three_value"; $db{'key1'}{'key2'}[2][1] = "four_value";

Or maybe like this, I'm not sure:

@{$db{'key1'}{'key2'}[0][0]} = "one_value"; @{$db{'key1'}{'key2'}[0][1]} = "two_value"; @{$db{'key1'}{'key2'}[1][0]} = "three_value"; @{$db{'key1'}{'key2'}[1][1]} = "four_value"; @{$db{'key1'}{'key2'}[2][0]} = "three_value"; @{$db{'key1'}{'key2'}[2][1]} = "four_value";

Now, under the key2 key, I don't know how many values are in that array. (The first set of array numbers, namely 0, 1, and 2). The second set of array numbers (The constant 0 and 1) are always there and only have the indexes 0 and 1.

Could someone please give me an idea what this hash structure would look like, and how I would go about getting the last index number of the first set of array numbers. (Something like $#{$db{'key1'}{'key2'}} maybe?)

And also, how would I go about deleting the array? I don't want to do delete $db{'key1'}{'key2'}, but something more along the lines of  delete $db{'key1'}{'key2'}[3].

Thanks ahead of time!

Replies are listed 'Best First'.
Re: Array in a Hash
by mstone (Deacon) on Dec 14, 2001 at 04:08 UTC


    >
    > I have this really annoying problem that I can't seem to figure
    > out... I need to create a hash that contains two sets of arrays
    > embedded. Editting the array in the hash would look like this:
    >
    > $db{'key1'}{'key2'}[0][0] = "one_value";
    > . . .

    that works..

    %db would be a hash whose keys map to hashrefs. the key 'key1' would be defined for that hash.

    %{ $db{'key1'} } would be a hash whose keys map to array refs. they key 'key2' would be defined for that hash.

    @{ $db{'key1'}{'key2'} } would be an array where each element is an array ref.

    @{ $db{'key1'}{'key2'}[0] } would be an array whose members are strings. the first element of that array would be "one_value".


    to find the contents of the outer hash, you can use:

    @outer_keys = keys %db;

    and you'll get an array of all keys that point to sub-hashes in the structure.


    to find the contents of a sub-hash, you can use:

    @inner_keys = keys %{ $db{'key1'} };

    and you'll get an array of all keys that point to 2D arrays within that sub-hash.


    to find out how many rows are in a particular 2D array, you can use:

    $rows = scalar @{ $db{'key1'}{'key2'} };


    and to find out how many columns are in a particular row, you can use:

    $cols = scalar @{ $db{'key1'}{'key2'}[0] };


    > Now, under the key2 key, I don't know how many values are in that
    > array.

    as mentioned above, this:

    $rows = scalar @{ $db{'key1'}{'key2'} };

    will tell you.


    > Could someone please give me an idea what this hash structure would
    > look like, and how I would go about getting the last index number of
    > the first set of array numbers. (Something like
    > $#{$db{'key1'}{'key2'}} maybe?)

    the value $rows, from the code above, will tell you how many items are in @{ $db{'key1'}{'key2'} }, but you need to remember the difference between counting (starts at 1) and indexing (starts at 0) to locate the index of the last item in that list.

    in other words, the number you're looking for is $rows-1.


    > And also, how would I go about deleting the array? I don't want to do
    > delete $db{'key1'}{'key2'}, but something more along the lines of
    > delete $db{'key1'}{'key2'}[3].

    popping is probably easiest:

    pop @{ $db{'key1'}{'key2'} };

    mike
    .

Re: Array in a Hash (boo);
by boo_radley (Parson) on Dec 14, 2001 at 03:02 UTC
    Could someone please give me an idea what this hash structure would look like, and how I would go about getting the last index number of the first set of array numbers. (Something like $#{$db{'key1'}{'key2'}} maybe?) And also, how would I go about deleting the array? I don't want to do delete $db{'key1'}{'key2'}, but something more along the lines of delete $db{'key1'}{'key2'}[3].
    @{$db{'key1'}{'key2'}[0][0]} = "one_value"; @{$db{'key1'}{'key2'}[0][1]} = "two_value"; @{$db{'key1'}{'key2'}[1][0]} = "three_value"; @{$db{'key1'}{'key2'}[1][1]} = "four_value"; @{$db{'key1'}{'key2'}[2][0]} = "three_value"; @{$db{'key1'}{'key2'}[2][1]} = "four_value"; print "how many elements does the array have : ", scalar (@{$db{'key1'}{'key2'}}); print "\n"; print "popping an element"; pop @{$db{'key1'}{'key2'}}; print "\n"; print "how many elements does the array have now : ", scalar (@{$db{'key1'}{'key2'}});

    now, if you want to do this in the middle of an array, you'll want to splice instead of pop. Some people may argue that popping isn't exactly the correct behavior here, since it's being called in a void context, so you might want to capture it, if need be.

Re: Array in a Hash
by premchai21 (Curate) on Dec 14, 2001 at 08:14 UTC
Re: Array in a Hash
by mt2k (Hermit) on Dec 14, 2001 at 19:29 UTC
    Okay, I did a little bit of research on my own to add to what you have given me... But what is the difference between these two snippets of code?:


    boo_radley's way, using @{$db{'key1'}{'key2'}[0][0]} = "one_value";, produces this hash:

    %db = ( 'key1' => { 'key2' => [ [ ['one_value'], ['two_value'] ], [ ['three_value'], ['four_value'] ] ] } );


    mstone's way, using $db{'key1'}{'key2'}[0][0] = "one_value";, produces this hash:

    %db = ( 'key1' => { 'key2' => [ [ 'one_value', 'two_value' ], [ 'three_value', 'four_value' ] ] } );


    The only difference between the two is that referencing it as an array (@{$db{...}}) adds square brackets around the values. But what difference does this create in reading/storing values?

    (Hash printout via Data::Dumper)

    UPDATE: So, I should use mstone's code?

      I was actually being bad-lazy; I copied the assignments from the original node without examining them too closely. The square brackets make array refs.