【问题标题】:Searching in a JSON array with Perl使用 Perl 在 JSON 数组中搜索
【发布时间】:2018-09-10 14:55:45
【问题描述】:

我需要在 JSON 数组中搜索特定术语并获取包含该术语作为键值的数组元素的索引,下面是我正在处理的示例 JSON 文件,我需要获取“artifact_id”为“jar”的数组元素,所以在这种情况下我需要获取数组的索引1,保证“artifact_id”是唯一的:

{
    "maven": [
      {
        "version": "1.2",
        "artifact_id": "zip"
      },
      {
        "version": "1.2",
        "artifact_id": "jar"
      }
    ]
}

我正在使用 JSON 库并且可以将 JSON 解码为 Perl 对象,任何人都可以为我建议下一步吗?非常感谢。

my $json_text = do {
               open( my $json_fh, "<:encoding(UTF-8)", $filename[0] )
               or die("Can't open \$filename\": $!\n");
               local $/;
               <$json_fh>;
};
my $json = JSON->new;
my $json_data = $json->decode($json_text);

【问题讨论】:

  • 如果您正在处理 JSON 和文件,可能值得查看提供 json_file_to_perlJSON::Parse。代替 8 行代码,您可以这样做:my $json_data = json_file_to_perl($filename); ...但是,嘿,手工制作是一个很好的起点并获得知识

标签: arrays json perl


【解决方案1】:

只需遍历您的数组,并在找到匹配节点后存储索引。下面的示例应该不言自明,但鉴于您帖子的内容,我想您应该阅读循环、比较运算符以及基本编程。

在解码完 JSON 数据之后,遍历数组并没有什么特别之处,毕竟;它只是一个数组(参考给定 JSON 的树状结构)。

use JSON qw(decode_json);

my $needle = "jar";
my $needle_location;

my $data = decode_json( join '', <DATA> );

while( my( $idx, $elem ) = each( @{$data->{'maven'}} ) )
{
    if( $elem->{'artifact_id'} eq $needle )
    {
        $needle_location = $idx;
        last;
    }
}

die "unable to find entry" unless defined $needle_location;
print "needle_location: $needle_location\n";

__DATA__
{
    "maven": [
      {
        "version": "1.2",
        "artifact_id": "zip"
      },
      {
        "version": "1.2",
        "artifact_id": "jar"
      }
    ]
}
needle_location: 1

【讨论】:

  • 谢谢!附带说明一下,Perl 5.10.x 不支持对数组进行迭代的each 支持(并且由于某种原因我无法更新到最新版本),所以我需要用for 循环替换它,比如` `` foreach my $idx (0 .. $#maven_array)```
【解决方案2】:

我的答案是基于Filip Roséen - refp 的答案,但希望是更高级和更简短的方法:

use Modern::Perl;

use List::Util qw(first);
use JSON qw(decode_json);

my $needle = "jar";
my $data = decode_json do { local $/; <DATA> };

my $needle_location = first( sub {
    my $artifact_id = $data->{ maven }->[ $_ ]->{ artifact_id };
    defined($artifact_id) && $artifact_id eq $needle
}, 0 .. $#{ $data->{ maven } } ) //
    die "unable to find entry";

say "needle_location: $needle_location";

__DATA__
{
    "maven": [
      {
        "version": "1.2",
        "artifact_id": "zip"
      },
      {
        "version": "1.2",
        "artifact_id": "jar"
      }
    ]
}

【讨论】:

    猜你喜欢
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 2016-01-15
    • 2021-09-22
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多