in reply to Re^2: Dump filtered subtree?
in thread Dump filtered subtree?

"it didn't look like I could provide multiple keys"

Ask and you shall receive. Oh wait, you didn't ask, well no matter...

#!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11111952 use warnings; use List::Util qw( none any ); use Data::Dump qw( dd ); sub subtree { my ($key, $tree) = @_; if( ref $tree eq 'ARRAY' ) { my @items = map [ subtree( $key, $_ ) ], @$tree; return +(none { $_->[0] } @items ) ? ( 0, []) : ( 1, [ map { $_->[0] ? $_->[1] : undef } @items ] ); } elsif( ref $tree eq 'HASH' ) { my @wanted; for my $k ( sort keys %$tree ) { if( matchkey( $key, $k ) ) { push @wanted, [ 1, $k => $tree->{$k +} ] } else { my ( $w, $t ) = subtree( $key, $tree->{$k} ); $w and push @wanted, [ $w, $k => $t ]; } } return @wanted > 0, +{ map { @{ $_ }[1, 2] } @wanted }; } else { return 0, $tree } } sub matchkey { my ($key, $here) = @_; any { $_ eq $here } ref $key ? @$key : $key; } sub pathforkey { my ($key, $tree, $sofar) = @_; if( ref $tree eq 'HASH' ) { return map { matchkey( $key, $_ ) ? $sofar . "{$_}" : (), pathforkey( $key, $tree->{$_}, $sofar . "{$_}" ) } sort keys %$tree; } elsif( ref $tree eq 'ARRAY' ) { return map { pathforkey( $key, $tree->[$_], $sofar . "[$_]" ) } 0 .. $#$tree; } else { return () } } my $tree = gettree(); dd 'original tree', $tree; print "\n"; my ($want, $subtree) = subtree( [ 'field', '_mcid' ], $tree ); dd "the subtree for 'field' ", $subtree; print "\nall paths to key 'field' :\n"; print "$_\n" for pathforkey( ['field', '_mcid'], $tree, '' ); sub gettree # slightly reduced... { my $tree = { 'cookies' => { '_AVESTA_ENVIRONMENT' => 'prod', '_mcid' => '1.340667ccb3eb6552450356561ab6bd92.' }, 'error' => '400 Bad Request', 'content' => { 'detail' => 'The resource specific details, \'errors\' array.', 'errors' => [ 'not this', { 'message' => 'This value of type obj +ect.', 'field' => 'merge_fields' } ], 'status' => 400, 'title' => 'Invalid Resource', 'type' => 'http://developer.mailchimp.', 'instance' => '59edf1fc-ed93-4a40-ba23-1f0af24a6eb3' }, 'code' => '400' }; }

Outputs:

( "original tree", { code => 400, content => { detail => "The resource specific details, 'errors' +array.", errors => [ "not this", { field => "merge_fields", message => " +This value of type object." }, ], instance => "59edf1fc-ed93-4a40-ba23-1f0af24a6eb3", status => 400, title => "Invalid Resource", type => "http://developer.mailchimp.", }, cookies => { _AVESTA_ENVIRONMENT => "prod", _mcid => "1.340667ccb3eb6552450356561ab6bd92.", }, error => "400 Bad Request", }, ) ( "the subtree for 'field' ", { content => { errors => [undef, { field => "merge_fields" }] }, cookies => { _mcid => "1.340667ccb3eb6552450356561ab6bd92." }, }, ) all paths to key : {content}{errors}[1]{field} {cookies}{_mcid}