Perl中如何用Hash of Arrays of Hashes嵌套结构实现计数
解决Perl中数组数组转嵌套计数哈希的问题
问题出在哪?
你之前用push的思路完全跑偏啦——push是给数组加元素的,但你的目标结构里,外层哈希的每个值应该是计数哈希(你示例里写的[ cat1 => 50 ]其实是Perl哈希的写法,大概率是笔误,正确的目标结构应该是嵌套哈希:{ cat1 => 50, cat2 => 3 })。用push只会把键值对当成数组元素塞进去,根本做不到计数累加的效果。
一步到位的解决方案
要在加载数据时直接完成计数,核心就是遍历你的数组的数组,对每一组数据(比如[var1, cat1]),直接定位到外层哈希对应的内层计数哈希,然后让对应分类的计数自增——Perl的哈希特性会帮你处理第一次出现的初始化问题,完全不需要分步处理。
举个具体的例子:
假设你的原始数据是这样的数组的数组:
my @raw_data = ( ['var1', 'cat1'], ['var1', 'cat1'], # ... 这里省略N条重复的var1/cat1、var1/cat2等数据 ['var2', 'cat2'], ['var2', 'cat4'], );
直接用这段代码就能生成你要的计数结构:
my %counts; foreach my $entry (@raw_data) { my ($var_key, $cat_key) = @$entry; # 关键就在这一行:直接让对应分类的计数自增 $counts{$var_key}{$cat_key}++; } # 可以用Data::Dumper验证结果 use Data::Dumper; print Dumper(\%counts);
运行后得到的%counts结构就是你想要的:
$VAR1 = { 'var1' => { 'cat1' => 50, 'cat2' => 3, 'cat3' => 5 }, 'var2' => { 'cat2' => 12, 'cat4' => 4, 'cat5' => 1 } };
为什么这能直接完成计数?
Perl哈希有个非常实用的特性:当你在数值上下文(比如++操作)中访问一个不存在的哈希键时,它会自动把这个键的值初始化为0,然后执行加1操作。所以第一次遇到$counts{$var_key}{$cat_key}时,它会变成1;之后每次遇到相同的键,就自动累加计数——完美实现了边加载边计数的需求。
如果你真的需要内层是数组(不推荐)
如果你的目标结构里内层必须是包含哈希的数组(虽然这种结构冗余且没必要),那你得先遍历内层数组找对应分类,找不到就push新的哈希进去,找到就累加计数。但真心建议用嵌套哈希,不管是读取还是维护都方便太多。
内容的提问来源于stack exchange,提问作者drmrgd
相关产品推荐
相关产品推荐

