G'day aturtle,
In order to get a better idea of how to write your code, perhaps the first thing to do would be to take a look at the general layout of your complete data structure (which is a hashref assigned to $form).
{ id => integer, cleared => boolean, PR => [ { ... }, ... { ... }, ], }
Now that the structure is clear, you should be able to see how misleading the first line of your outer loop is:
foreach my $key ( @{ $form->{PR} } ) {
Each of the elements in @{ $form->{PR} } are hashrefs, not keys.
You attempt to clarify this (by writing unnecessary code) with my %elem = %{$key}; however, you've possibly confused yourself even more because right below this you assign an actual key to another misleadingly named variable ($var) and then make the mistake of using it as a hashref (i.e. $var->{id}):
foreach my $var ( keys %elem ) { if ($var->{id} == $form->{"id"}){
A logical indentation of your code would make it easier to both read and maintain. I didn't find it easy to understand without close study (which shouldn't be necessary for fairly straightforward code such as this). This poor layout may well have been a contributing factor in some of the errors you've made. You can get some hints and tips on how to improve this from "perlstyle - Perl style guide"; you can use perltidy to reformat your code to your chosen style.
I'd also recommend you read UNIVERSAL. In the SYNOPSIS, you'll see "but never do this!" followed by examples similar to usages in your code. The ref function would have been a better choice here; also see the reftype function in the built-in Scalar::Util module.
Here's an example of how I might have searched through your data structure and made conditional changes to it:
#!/usr/bin/env perl -l use strict; use warnings; use Data::Dumper; my $form = { id => 12594, cleared => 1, PR => [ { id => 10368, cleared => 0 }, { id => 12594, cleared => 0 }, ], }; print '*** BEFORE ***'; print Dumper $form; for my $hash_ref (@{$form->{PR}}) { if ($hash_ref->{id} == $form->{id}) { $hash_ref->{cleared} = $form->{cleared}; } } print '*** AFTER ***'; print Dumper $form;
Output:
*** BEFORE *** $VAR1 = { 'cleared' => 1, 'id' => 12594, 'PR' => [ { 'cleared' => 0, 'id' => 10368 }, { 'cleared' => 0, 'id' => 12594 } ] }; *** AFTER *** $VAR1 = { 'cleared' => 1, 'id' => 12594, 'PR' => [ { 'cleared' => 0, 'id' => 10368 }, { 'cleared' => 1, 'id' => 12594 } ] };
[Also consider using Data::Dump. In many instances, it's a better choice than Data::Dumper.]
-- Ken
In reply to Re: how to loop each anonymous hash in an array of hashes
by kcott
in thread how to loop each anonymous hash in an array of hashes
by aturtle
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |