http://www.perlmonks.org?node_id=985899


in reply to Iterative HOH or AOH?

In addition to the issue of assigning default values in the cases where your input data provides none, you also have the issue that your input data has a variable organization. The value of the ProductVersion key might be a reference to an anonymous hash containing the details of a single product version or it might be a reference to an anonymous hash with a key for each of several product versions, where each key is the 'name' of the product version and each value is a reference to an anonymous hash containing the details of that product version (except for the name field, which is the key value).

OK, even I can't read that, and I like words. What I would do is normalize the structure, then process that, maybe like this:

foreach my $product (keys %sw) { print "Now processing $product\n"; my $version = '0'; my $release = '0'; my $description = $sw{$product}{'description'}; my $vendorUniqueKeyRef = $sw{$product}{'vendorUniqueKeyRef'}; my $swUniqueKey = $sw{$product}{'swUniqueKey'}; if ($sw{$product}{ProductVersion}) { if(exists($sw{$product}{ProductVersion}{name})) { # Push the immediate hash down, keyed by name # ignoring the duplicate name field $sw{$product}{ProductVersion} = { $sw{$product}{ProductVersion}{name} => $sw{$product}{P +roductVersion} }; } foreach my $product_version_name (keys %{$sw{$product}{Product +Version}}) { if($sw{$produt}{ProductVersion}{$product_version_name}{Pro +ductReleaseVersion}) { if(exists($sw{$produt}{ProductVersion}{$product_versio +n_name}{ProductReleaseVersion}{name})) { # Push the immediate hash down, keyed by name # ignoring the duplicate name field $sw{$produt}{ProductVersion}{$product_version_name +}{ProductReleaseVersion} = { $sw{$produt}{ProductVersion}{$product_version_ +name}{ProductReleaseVersion}{name} => $sw{$produt}{ProductVersion}{$product_vers +ion_name}{ProductReleaseVersion}; }; } foreach my $product_version_release_name (keys %{$sw{$ +product}{ProductVersion}{$product_version_name}{ProductReleaseVersion +}}) { # Print / store a record for the case that there i +s both a ProductVersion and ProductReleaseVersion } } else { # Print / store a record for the case that there is a +ProductVersion but no ProductReleaseVersion } } } else { # Print / store a record for the case that there is no Product +Version (and, therefore, no nested ProductReleaseVersion) } };

I haven't actually printed the output. I would probably do that with some subroutines to avoid duplication, and set defaults if values are missing.