Link to home
Start Free TrialLog in
Avatar of SapphireGirl
SapphireGirlFlag for United States of America

asked on

Writing and accessing an Array of Non-Anonymous hashes

How do you write a array of non-anonymous hashes

I thought I could do it this way.

my @Arrayofhashes = (
            NameofHash => {
            var1      => "frodo",
            var2      => "gandalf",
            var3      => "sam" },
           
  );

Would it be valid to define an array of hashes like this?

my @Arrayofhashes = (
            TolkenCharacters => {
            var1      => "frodo",
            var2      => "gandalf",
            var3      => "sam" },

           TolkenCharacters => {
            var1      => "merry",
            var2      => "pippin",
            var3      => "smeagol" },
           
  );

Or would it have to be like this.

my %namedhash = (
            TolkenCharacters => {
            var1      => "legolas",
            var2      => "gandalf",
            var3      => "smeagol" },

           HobbitCharacters => {
            var1      => "merry",
            var2      => "pippin",
            var3      => "sam" },
           
  );

Now, How do I access say smeagol or sam?

When looping thru an array of say 100 hashes, is it best to use an array of anonymous hashes?
I confused about  why to use named hashes.

Thank you
Avatar of ozo
ozo
Flag of United States of America image

my %namedhash = (
            TolkenCharacters => {
            var1      => "legolas",
            var2      => "gandalf",
            var3      => "smeagol" },

           HobbitCharacters => {
            var1      => "merry",
            var2      => "pippin",
            var3      => "sam" },
           
  );

print $namedhash{TolkenCharacters}{var3};

print $namedhash{HobbitCharacters}{var3};
@Arrayofhashes = (
            TolkenCharacters => {
            var1      => "frodo",
            var2      => "gandalf",
            var3      => "sam" },

           TolkenCharacters => {
            var1      => "merry",
            var2      => "pippin",
            var3      => "smeagol" },
           
  );
This is an array with a scalar in $Arrayofhashes[0], a hash in $Arrayofhashes[1], a scalar in  $Arrayofhashes[2], and a hash in  $Arrayofhashes[3];
an array of just hashes would be

@Arrayofhashes = (
            {
            var1      => "frodo",
            var2      => "gandalf",
            var3      => "sam" },

            {
            var1      => "merry",
            var2      => "pippin",
            var3      => "smeagol" },
           
  );
then $Arrayofhashes[0]{var3} eq "sam" and $Arrayofhashes[1]{var3 } eq "smeagol"

but with keys like 'var1'..'var3'  it may more sense to use a hash of arrays:

%HoA=(
            TolkenCharacters => [
             "legolas",
             "gandalf",
             "smeagol" ],

           HobbitCharacters => [
             "merry",
             "pippin",
            "sam" ],
           
  );
Avatar of SapphireGirl

ASKER

Great,  Now how could I iterate thru the hash of arrays to print out each character.

Also,  Do you have recommendations for a good book on

1.  Creating and using advance data structures in Perl
2.  Creating good object oriented classes (base and inherited) in Perl
3.  Created reusable interfaces and modules in Perl

I have googled until I cannot google anymore ;)
you might start with
perldoc perllol
%HoA=(
            TolkenCharacters => [
             "legolas",
             "gandalf",
             "smeagol" ],

           HobbitCharacters => [
             "merry",
             "pippin",
            "sam" ],
           
  );

print "@$_\n" for values %HoA;
Perfect ozo.  Checked out the perllol too and is was great.

Why and when does one used named hashes?  Can you give an example of how to access HobbitCharacters using the name?  Say I have a hash of 5 arrays with 3 named TolkenCharacters and 2 named HobbitCharacters.  Is that legal to do if the values in the hashes are different?

Here is an example of the HoA

%HoA=(
            TolkenCharacters => [
             "legolas",
             "gandalf",
             "smeagol" ],

            TolkenCharacters => [
             "Nazgul",
             "eagles",
             "shelob" ],


            TolkenCharacters => [
             "Smaug ",
             "gandalf",
             "Aragorn" ],


           HobbitCharacters => [
             "frodo",
             "sam",
            "merry" ],

          HobbitCharacters => [
             "pippin",
             "brandybucks",
             "baggins" ],
           
        OrcCharacters => [/@OrcArray],
  );

Ok, here are 3 types of named arrays in my hash.  Is that correct.

How to I access each of these 3 types of structures iteratively
1.  TolkenCharacters
2.  HobbitCharacters
3.  OrcCharacters

I think 1 and 2 will be similar but putting the complexity of a reference to an array, how can I extract the data in a clean fashion.

I want to be able to understand the syntax enough to start using these complex data structures in Perl.

Thank you.
Avatar of Adam314
Adam314

With your %HoA, you can't have the same key more than once.  So in this case, the later key/value pair will replace the earlier one.  So you will end up with the keys TolkenCharacters, HobbitCharacters, and OrcCharacters - but only 1 of each.
With your OrcCharacters, you will probably want either this:
    OrcCharacters => [@OrcArray]
Or this:
   OrcCharacters => \@OrcArray
You probably do not want to use the square brackets and the backslash.  The backslash creates a reference to the named array (@OrcArray in this case).  The square brackets creates a new array with the data from the named array.  The difference is that if you use the backslash, and then make changes to ether $HoA{OrcCharacters} or @OrcArray, these changes will be reflected in the other - as they refer to the same data.  While if you use square brackets, they would be seperate arrays, and changes in one would not affect the other.

You can access things like:
    $HoA{$key}
    where $key is either "TolkenCharacters", "HobitCharacters", or "OrcCharacters"
    This will give you a reference to an array
You can then access one of the array elements with
    $HoA{$key}->[$index]
    where $index is the index number into the array
    you can eliminate the -> if you prefer:
    $HoA{$key}[$index]


Ok, for the 2 named arrays I think I can do this.

Given the HoA defined above:  Is this right
1.  The refence OrcCharacters doesn't work -> commented out.

Then the below code
#------------------------------------
 # print the whole thing
 foreach $typeofCharacter ( keys %HoA ) {
     print "$typeofCharacter: @{ $HoA{$typeofCharacter} }\n"
 }
#-----------------------------------------------------------------------------
printed out this:
TolkenCharacters: Smaug  gandalf Aragorn
HobbitCharacters: pippin brandybucks baggins


It only printed the last Tolken element or the last Hobbit Character.
What is wrong here.

I got this from perllol.
ASKER CERTIFIED SOLUTION
Avatar of Adam314
Adam314

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you very much.