in reply to Re: Recursive data structure munging - arrayrefs to hashrefs
in thread Recursive data structure munging - arrayrefs to hashrefs

First, the data structure you've shown isn't actually valid: $foo = { ... }; is missing a hash key, so for now I'm just going to assume $foo = { foo => ... };

Thanks - that was, obviously, incorrect. The structure does not necessarily alternate between @ and % - but I'm fairly certain that there's no AoA component anywhere (and lots of HoH structures.)

Your code works for $foo, but unfortunately not for the more complex structure - "Not an ARRAY reference" errors, unsurprisingly. I'm pretty sure it's that assumption that the next level down must be an array... as I've said, it's arbitrary depth. I appreciate your effort, though!

  • Comment on Re^2: Recursive data structure munging - arrayrefs to hashrefs

Replies are listed 'Best First'.
Re^3: Recursive data structure munging - arrayrefs to hashrefs (updated x2)
by haukex (Archbishop) on Aug 31, 2017 at 20:30 UTC
    Your code works for $foo, but unfortunately not for the more complex structure

    Well, as I said, easily fixed with an if. More representative sample input data gets you better answers ;-) The following should work on AoH and HoH, but not yet on AoA, and the root must be a hash. Extending this further is left as an exercise to the reader...

    sub rekey { my $h = shift; KEY: for my $k (keys %$h) { if (ref $$h{$k} eq 'ARRAY') { rekey($_) for @{$$h{$k}}; my %n; for my $e (@{$$h{$k}}) { next KEY unless exists $$e{name}; die "duplicate key '$$e{name}'" if exists $n{$$e{name}}; $n{$$e{name}} = $e; } $$h{$k} = \%n; } elsif (ref $$h{$k} eq 'HASH') { rekey($$h{$k}) } } } rekey( $foo );

    Update: I realized based on the sample data that you posted here that not all of your hashes in the AoHs have "name" keys. So I modified the above to skip transforming such AoHs with next KEY unless exists $$e{name};. Other approaches are of course possible too, if you can identify a useful key. Update 2: I applied that change a little too hastily, it wasn't correct as it wasn't recursing into the full data structure anymore. Fixed.