如何使用perl

时间:2019-05-02 07:11:38

标签: json perl

{

  "root1" : {
      "sub1" : null,
      "sub2" : {
         "subsub1" : {
            "key1" : {

            },
            "key2" : {

            },
            "key3" : {

            },
            "key4" : {

            }
         }
      },
      "sub3" : {
         "subsub2" : {
            "key5" : {

            }
         }
      }
  },
  "root2" : {
      "sub1" : null,
      "sub2" : {
         "subsub1" : {
            "key1" : {

            },
            "key2" : {

            },
            "key3" : {

            },
            "key4" : {

            }
         }
      },
      "sub3" : {
         "subsub2" : {
            "key8" : {

            }
         }
      }
  }
}

考虑上述json。 如何知道此json中是否存在“ key8”,以及如何在json中找到其所在的路径。

例如,如果搜索“ key8”,则需要获得类似于以下内容的输出:

root2->sub3->subsub2->key8

1 个答案:

答案 0 :(得分:3)

这只是一个简单的树遍历。找到匹配项后,就会立即返回以下内容(而不是查找所有匹配项)。

sub key_search {
    my $target = $_[1];   
    my @todo = [ $_[0] ];
    while (@todo) {
        my ($val, @path) = @{ shift(@todo) };
        my $reftype = ref($val);
        if (!$reftype) {
           # Nothing to do
        }
        elsif ($reftype eq 'HASH') {
           for my $key (keys(%$val)) {
              return @path, $target if $key eq $target;

              push @todo, [ $val->{$key}, @path, $key ];
           }
        }
        elsif ($reftype eq 'ARRAY') {
           for my $i (0..$#$val) {
              push @todo, [ $val->[$i], @path, $i ];
           }
        }
        else {
           die("Invalid data.\n");
        }
    }

    return;
}

my @path = key_search($data, 'key8')
   or die("Not found.\n");

注释

  • 如果数据可以包含数组,并且任何哈希可以具有键的整数,则结果是不明确的。可以采取步骤消除它们的歧义。
  • 以上内容不检查循环,但这些循环在JSON中不存在。
  • push替换为unshift,以进行深度优先搜索,而不是宽度优先搜索。