Clark family has 4 members name: Mary Smith name: Lisa Clark family has 1 members

I have the syntax for extracting (ShowFamilyMember) data from the outer array of hash references and also the inner array of hash references.

I can’t figure out the proper syntax for adding another family member to the inner array of hash references. The first output line shows that the Clark family has 4 members as the reference to the array of hashes is stored in the family hash.

The last line or output shows that that same array has only one member when I try to retrieve it from the hash.

The inner array of family member hashes has to be properly stored in the outer array of family hashes or the Show Family Member sub would not get the proper first names. What is the proper syntax for second line of AddFamilyMember so the last line tell the correct family size?

Clark family has 4 members name: Mary Smith name: Lisa Clark family has 4 members name: Timmy Clark

Pardon my “C” talk here, but is there a way of extracting a “pointer” to the array in the second line of Add Family Member so that the last line which replaces the array in the family’s hash is not necessary?

The main and Show Family subs are the same as in my first post.

Main creates an array of two hash references [0] and [1]. The initial code creates array of 4 hash references for the members of the second family [0] through [3].

The new Add Family Member sub now extracts the family members array from the family hash and pushes the new member onto that stack as a fifth member [4].

Show Family Member ( 1, 4 ) can now display the new member of that family.

Re: [PapaGeek] Extracting an Array of Hashes from an Array of Hashes
[In reply to]

Can't Post

It is probably a good idea to do it stepwise as you did, expecially if you are not yet fully fluent with nested data structures, as it may be argued that this is clearer. But if you really want to reduce the number of steps, you could use directly anonymous hash refs. This should probably work (not tested):

Re: [PapaGeek] Extracting an Array of Hashes from an Array of Hashes
[In reply to]

Can't Post

When I answered with the piece of code above, I forgot to address some of your questions.

In Reply To

Pardon my “C” talk here, but is there a way of extracting a “pointer” to the array in the second line of Add Family Member so that the last line which replaces the array in the family’s hash is not necessary?

It is probably not a very good idea to think in C terms, Perl is much more expressive than C, thinking in C terms will reduce your own expressivity. But the answer is yes, it is possible and quite easy, with the references that you already have at hand.

This line:

Code

my @members = @{$Families[$Family]{"Members"}};

is actually dereferencing the

Code

$Families[$Family]{"Members"}

reference to copy its content into the @members array. If you work directly on the reference, rather than on a copy of its content, you obtain the same effect that what you decribe in terms of C pointers. So, besides the very compact solution I posted above, this is another solutionb that is closer to your original code:

Because we now work on a reference which is a copy of the original array ref (rather than on a copy of the array content), we no longer need to do the data copying of the last line of your code: any change we do is done on the original data, on the content of the Families array.

Pushing it one step further, you don't even need the $members_ref array reference but can work directly on $Families[$Family]{"Members"} which is itself an array ref:

The key I got from your last post was to collect the members reference as a $ reference, and again in “C” terms, recast it as an array with the @$ syntax.

The new code works great and is exactly what I was looking for. Thanks again!

I’m not sure if I will use your first solution or the step further solution, but they both work.

My actual code is managing a list of stock market symbols and the amount invested in each. The amount is displayed in a Tk::Entry widget which requires a unique location for the input / edited output for each widget. That is primary reason I needed an array of Hashes.

Re: [PapaGeek] Extracting an Array of Hashes from an Array of Hashes
[In reply to]

Can't Post

Hi PapaGeek, Pedagogically, it was a mistake on my part to first present the most concise solution, and then to come back with intermediate steps. Sorry about that, I originally wanted to give you a solution, and then only figured out that it might be useful to give you the idea in intermediate steps. Use whichever solution you feel comfortable with right now, but I tend to think that, in a year from now, facing ther same or a similar issue, you'll go for the first solution I posted. Once you understand it, it is really simpler.

But, asides from the solutions I provided, as useful as they may be, I really hope that I helped you understand what is going on with these complex data structure and the underlying references. It also took me a few weeks, or possibly even a couple of months to really understand these things when I first came across them, but once you really grasp them, you can write really efficient code (efficient in terms of coding conciseness, that is). To me, the solution in my first post is the clearest one, because there is essentially only one line of code to look at, I do not need to memorize the content of intermediate variables. But I certainly agree that people beginning to use these concepts might need the intermediary steps to be comfortable with the solution.

Re: [PapaGeek] Extracting an Array of Hashes from an Array of Hashes
[In reply to]

Can't Post

Hi PapaGeek, If I may add my voice to the solutions already given, I will say:

1. You might have to read perldsc documentation as you take on complex data structure. It will help you on the long run. You can get this on your system thus

Code

perldoc perldsc

2. I think it might be a lot easily if you start thinking on doing what you intended in here using perl5 OO! Of course Moose and several of it's cousins comes to mind which is the way to go doing OO perl5 in modern times. However, I will show how your script might be if you are using the boilerplate of perl OO.

Note that, you don't have to physically declare an hash for each member of a family, monitoring each person. You can simply add and get family member's name and age if you want. Since which family member has it's identity in his/her class, even if they have the same and live in the place. As long as they are in different class you are covered.

You can take the Families package to a different file named after it's name with an extension of

Code

.pm

then use stating

Code

use Families;

my $family = Families->new( {...} ); ...

Like I mentioned above a better way to go is use Moose or Moo and their different cousins! The code above is to illustrate ( though works ) that OO will be better, cleaner and easier to maintain later.