我有一个从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
作为命名元素的哈希?
答案 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];