Perl:哈希数组-获取ID为哈希值的元素

时间:2018-08-27 13:06:48

标签: perl

我有一个从json加载的Perl数据结构,Data::Dumper看起来像这样:

    $VAR1 = {
          'Stat' => [
                      {
                        'statCfgFile' => 'statcfg_0001.json',
                        'statid' => 1,
                        'status' => 'running',
                        'something' => 'other'
                      },
                      {
                        'statCfgFile' => 'statcfg_0002.json',
                        'statid' => 2,
                        'status' => 'running'
                        'something' => 'other'
                      }
           ]
}

从另一个数据集中,我得到一个statid以读取哈希,但是给定的id与数组键不匹配,因此我需要深入研究statid属性。

当然,我可以遍历整个数组,但是数组列表很大,可能会影响性能。

是否可以通过散列中存储的statid直接访问数组元素?

由于数据模型掌握在我手中,并且正在开发中: 最好不使用数组,而使用statid作为命名元素的哈希?

2 个答案:

答案 0 :(得分:0)

如果statid字段是唯一的,那么我建议您使用更多类似的内容

{
    1 => 'statcfg_0001.json',
    2 => 'statcfg_0002.json',
}
  

散列包含的数据多于显示的数据。我扩展示例

然后您需要一个哈希值,而不是每个statid

的字符串值
{
    1 => {
        statCfgFile => 'statcfg_0001.json',
        statid      => 1,
        status      => 'running',
        something   => 'other',
    },
    2 => {
        statCfgFile => 'statcfg_0002.json',
        statid      => 2,
        status      => 'running',
        something   => 'other',
    },
}

答案 1 :(得分:0)

简短的回答是“否”,您不能在不迭代数组的情况下根据条件从数组中提取值。但是有一些不用循环就可以编写它的方法。

假设数据结构为$data,并且您想在statid等于$id_to_find的地方散列哈希值。

my @matching_hashes = grep {$_->{statid} = $id_to_find}} @{$data->{Stat}};

如果只有与ID匹配的第一个哈希是相关的,则可以使用核心模块List::Util函数first,其功能与grep相同,但只返回第一个匹配项列表中。它会比grep更快,因为一旦找到一个匹配项,它就会停止对数组进行迭代。

use List::Util 'first';
my $matching hash = first {$_->{statid} = $id_to_find}} @{$data->{Stat}};

正如您所指出的,使用哈希查找比列表操作快得多。您可以创建数组地址的哈希索引。注意,这仍然需要您遍历数组一次。

# create the index;
my %index;
my @array = @{$data->{Stat}};
for my $address (0..$#array) {     # "$#array" is the last element of @array
    my $hash = $array[$address];
    my $id = $hash->{statid};
    $index{$id} = $address;        # now you can use an ID to get the array address
}

# use the index
my $id_to_find = 42;
my $wanted_array_address = $index{$id_to_find};
my $matching_hash = $data->{Stat}->[$wanted_array_address];