• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 396
  • Last Modified:

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
0
SapphireGirl
Asked:
SapphireGirl
  • 5
  • 4
  • 2
2 Solutions
 
ozoCommented:
my %namedhash = (
            TolkenCharacters => {
            var1      => "legolas",
            var2      => "gandalf",
            var3      => "smeagol" },

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

print $namedhash{TolkenCharacters}{var3};

print $namedhash{HobbitCharacters}{var3};
0
 
ozoCommented:
@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" ],
           
  );
0
 
SapphireGirlAuthor Commented:
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 ;)
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
ozoCommented:
you might start with
perldoc perllol
0
 
ozoCommented:
%HoA=(
            TolkenCharacters => [
             "legolas",
             "gandalf",
             "smeagol" ],

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

print "@$_\n" for values %HoA;
0
 
SapphireGirlAuthor Commented:
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.
0
 
Adam314Commented:
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]


0
 
SapphireGirlAuthor Commented:
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.
0
 
Adam314Commented:
>>Given the HoA defined above:  Is this right
>>1.  The refence OrcCharacters doesn't work -> commented out.
Well, you have a forward slash instead of a backslash.  Other than that, it's not wrong, it just probably not what you wanted.  The backslash gives you a reference to the array, then the square brackets give you a reference to another array.  So for that 1 value, you end up with a hash, where the value is the reference to an array, and that array has a single element that is a reference to the @OrcCharacters array.  You would access it with:
    $HoA{OrcCharacters}->[0]->[$index]
    where $index is the index number into @OrcCharacters.  You can, if you prefer, leave off the ->.


>>It only printed the last Tolken element or the last Hobbit Character.
>>What is wrong here.
Nothing is wrong.  That is the way hashes work.  A given key can only be in the hash one time.  So, the second, and then the third, TolkenCharacters key (and its value) replaced the previous ones.  Likewise, the second HobbitCharacters key (and its value) replaced the previous one.
0
 
ozoCommented:
#you could do
%HoA=(
            TolkenCharacters => [
             "legolas",
             "gandalf",
             "smeagol"

             "Nazgul",
             "eagles",
             "shelob"

             "Smaug ",
             "gandalf",
             "Aragorn" ],
)
#or
%HoAoA=(
            TolkenCharacters => [
             [
             "legolas",
             "gandalf",
             "smeagol" ],

             [
             "Nazgul",
             "eagles",
             "shelob" ],

             [
             "Smaug ",
             "gandalf",
             "Aragorn" ],
         ]
)
0
 
SapphireGirlAuthor Commented:
Thank you very much.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 5
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now