Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl grep嵌套哈希递归_Perl_Hash_Nested - Fatal编程技术网

Perl grep嵌套哈希递归

Perl grep嵌套哈希递归,perl,hash,nested,Perl,Hash,Nested,我有这样的结构(散列): 我想用“val2”过滤这个嵌套结构 输出应为: %result=( Level1_1=> { Level2_2=> { Level3_1 => "val2"} }, Level1_2=> { Level2_2=> { Level3_2 => "val2" } }, Level1_3=> { Level2_2 => "val2" } ); 我的第一个想法是使用如下递归子程序: hashwal

我有这样的结构(散列):

我想用“val2”过滤这个嵌套结构 输出应为:

%result=(
    Level1_1=> { Level2_2=> { Level3_1 => "val2"} },
    Level1_2=> { Level2_2=> { Level3_2 => "val2" } },
    Level1_3=> { Level2_2 => "val2" }
    );
我的第一个想法是使用如下递归子程序:

hashwalk_v( \%hash );
sub hashwalk_v
{
    my ($element, @array) = @_;
    if( ref($element) =~ /HASH/ )
    {
   while (my ($key, $value) = each %$element)
   {

     if( ref($value) =~ /HASH/ ) {
      push (@array, $key);
      hashwalk_v($value, @array);
     } else {
      if ( $value =~ "val2") {
       push (@array, $key);
       print $_ .  "\n" for @array;
      } else {
       @array =""; 
      }
     }
   }
 }
}
但不幸的是,我无法保存上一个循环中的哈希键。
有什么想法吗?

递归是正确的答案,但您似乎一路上有些困惑一次构建一个新的哈希:

sub deep_hash_grep {
    my ($hash, $needle) = @_;

    my $ret = {};
    while (my ($key, $value) = each %{$hash}) {
        if (ref $value eq 'HASH') {
            my $subgrep = deep_hash_grep($value, $needle);
            if (%{$subgrep}) {
                $ret->{$key} = $subgrep;
            }
        }
        elsif ($value =~ $needle) {
            $ret->{$key} = $value;
        }
    }

    return $ret;
}
类似的方法

use Data::Dumper; print Dumper hfilter(\%hash, "val2");

sub hfilter {
  my ($h, $find) = @_;
  return if ref $h ne "HASH";

  my %ret = map {
    my $v = $h->{$_};
    my $new = ref($v) && hfilter($v, $find);

    $new ? ($_ => $new)
      : $v eq $find ? ($_ => $v)
      : ();

  } keys %$h;

  return %ret ? \%ret : ();
}
use Data::Dumper; print Dumper hfilter(\%hash, "val2");

sub hfilter {
  my ($h, $find) = @_;
  return if ref $h ne "HASH";

  my %ret = map {
    my $v = $h->{$_};
    my $new = ref($v) && hfilter($v, $find);

    $new ? ($_ => $new)
      : $v eq $find ? ($_ => $v)
      : ();

  } keys %$h;

  return %ret ? \%ret : ();
}