Perl grep 嵌套哈希递归

标签 perl hash nested

我的结构如下所示(哈希值的哈希值):

%hash=(
Level1_1=> {    
 Level2_1 => "val1",
 Level2_2=> { 
  Level3_1 => "val2",
  Level3_2 => "val1",
  Level3_3 => "val3",
 },
Level2_3 => "val3",
},
 Level1_2=> {   
  Level2_1 => "val1",
  Level2_2=> {  
   Level3_1 => "val1",
   Level3_2 => "val2",
   Level3_3 => "val3",
  },
 Level2_3 => "val3",
 },
 Level1_3=> {   
  Level2_1 => "val1",
  Level2_2 => "val2",
  Level2_3 => "val3",
 });

我想 grep 这个由“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 =""; 
      }
     }
   }
 }
}

但不幸的是我无法保存上一个循环中的哈希键。 有什么想法吗??

最佳答案

类似的方法,

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 : ();
}

关于Perl grep 嵌套哈希递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19629513/

相关文章:

perl - 如何使用 Test::Class::Load 运行单独的测试?

perl - Perl 中的输出流 : STDERR, STDOUT,

mysql - 找不到 DBI.pm,即使它在路径中

java - 无法使用 for 循环添加空格分隔的输入

php - 如何按嵌套集中的类别名称获取产品列表

python - 如何使用 zip 连接深层嵌套列表的最里面的元素

perl - 为什么 WWW::Mechanize 获取某些页面而不是其他页面?

python - 在 python 中加密

javascript - Javascript 中的 CityHash

java - 创建独立的哈希函数