Perl中散列的散列方式
前(伪代码):
我的%哈希=();
$hash{key1}{key2} = ['', '', '', . 。 .];
任何一个
$hash{key1}{key2} = @;
基本上,我希望能够对任意数量的键组合执行此操作,并且能够迭代所有可能的键/值对(或更正确的键、键/数组对,因为每个值实际上是一个值,并且每个array 有 2 个与之关联的键)并按以下格式打印输出:
“键1,键2,,,,....n”
例如:
10
11
12
13
14
15
16
17 号
18
19 号
20
21
22
23
24
25
26
27 号
28
29
#!/usr/bin/perl
使用 ;
使用 ;
# 哈希
我的%哈希=();
我的$ =“”;
我的$ =“”;
# 推入哈希
推@{$hash{a}{b}},$;
推@{$hash{a}{b}},$;
推@{$hash{c}{d}},$;
推@{$hash{c}{d}},$;
# 打印哈希值
#(想要将其作为所有键/值对的循环)
本地 $, = ',';
打印“a,b,”;
打印@{$hash{a}{b}};
打印”
”;
打印“c,d,”;
打印@{$hash{c}{d}};
打印”
”;
('暂停');
该代码的输出如下所示:
甲、乙、、
光盘, ,
按任意键即可。 。 。
我正在考虑使用 every 运算符,但它似乎只适用于一维哈希。 (每个只返回一个键值对,当涉及两个键时将无法正常工作)
如何简化此代码以循环散列并打印所需的输出,无论我获得多少个散列?
即使对于多级哈希,使用每个都可以正常工作,您只需要确保参数是哈希。 下面是如何执行此操作的示例。 我还展示了如何初始化您的哈希。
10
11
12
13
14
15
16
17 号
18
19 号
20
使用 ;
使用 ;
使用v5.14;
我的$ =“”;
我的$ =“”;
我的%哈希=(
一个=> {
b => [ $, $ ],
},
c => {
d => [ $, $ ],
);
对于我的 $key (keys %hash) {
while (my ($k, $v) = every %{ $hash{$key} }) {
说加入",", $key, $k, @$v;
输出:
光盘, ,
甲、乙、、
请注意,使用 @$v 到达最里面的数组很简单,而不是使用有点麻烦的替代方法 @{ $hash{$key}{$k} }。
这是使用递归子例程的最巧妙的方法,并且由于它只递归几次,所以这不是一个浪费的解决方案。
10
11
12
13
14
15
16
17 号
18
19 号
20
21
22
23
24
使用 ;
使用 ;
我的%哈希;
我的($,$)=qw//;
推@{$hash{a}{b}},$;
推@{$hash{a}{b}},$;
推@{$hash{c}{d}},$;
推@{$hash{c}{d}},$;
(\%哈希值);
子{
我的($ref,$)=(@_,'');
if (ref $ref eq 'ARRAY') {
打印 $, join(', ', @$ref),"
”;
别的 {
($ref->{$_},"$$_,") 用于排序键 %$ref;
输出
甲、乙、、
光盘, ,
您还没有解释为什么要打印 HoHoA (数组哈希)的内容。 如果出于调试目的,我会使用 Data::(核心)或 Data::Dump(在 CPAN 上)。
使用数据::qw();
打印\%哈希值;
任何一个
使用 Data::Dump qw(pp);
pp \%哈希;
假设您需要格式化每个示例的输出(并且它始终是 HoHoA 所独有的),我将使用嵌套循环:
while (my ($ok, $ov) = every %hash) {
while (我的($ik, $iv) = 每个%$ov) {
说加入 ',', @$iv;
我不建议使用地图。 它更适合用于列表转换而不是流控制,并且使用嵌套映射块来跟踪外键和内键很尴尬。 既然您和 G. Cito 表示有兴趣看到一个,这里是:
说地图{
我的 $o = $_;
地图 {
我的 $i = $_;
连接 ',', $o, $i, @{$hash{$o}{$i}}
} 键 %{$hash{$o}};
} 键 %hash;
要打印数组的哈希值的哈希值,您可以使用或 for my 迭代数据结构:
10
11
12
13
14
# 外部哈希的键
我的 $oh (keys %hash) {
# 内部哈希的键
我的 $ih (键 %{$hash{$oh}}) {
# $hash{$oh}{$ih} 是数组,所以可以这样:
打印 join(",", $oh, $ih, @{$hash{$oh}{$ih}}) 。"
”;
# 或者你可以像这样的项目:
# 我的 $arr (@{$hash{$oh}{$ih}})
# { ($arr); }
对于所有地图迷来说,这里有一个地图版本:
地图{我的$oh = $_;
地图 { 说 join(",", $oh, $_, @{$hash{$oh}{$_}} ) } 键 %{$hash{$_}}
} 键 %hash;
我要求它:-( ...“嵌套地图”(??)。
#!perl -l
我的%哈希=();
$hash{key1}{key2} = ['', '', '',];
地图{ &{ 子{
映射{ print for @{$hash{$_[0]}{$_}}} 键 $hash{$_} }}($_)} 键 %hash;
输出:
注意:从技术上讲,我认为(在幕后)这仍然是一个循环,而且效率不高。 看来,如果您“嵌套”对 map 的调用并使用匿名子({& sub { .. 位)包装内部 map{} ,您可以通过 @_ 引用外部地图主题值(即在 $_[ 0 ] 因为它们进入内部映射... ...但只有当它们位于列表上下文中时 ($_)... errm(?!?) 好吧,我只是在这里掌握它的窍门。
不管怎样,它有效,但看起来比应有的更混乱——可能是因为它是一种“反模式”。 好处之一是它使“嵌套 for 循环”看起来不那么混乱并且更易于阅读。
听起来你需要一个嵌套循环......可能有一种方法可以使用地图来做到这一点,它更难记住并且可读性较差;-)(当然,这只是为我自己说话 - 我非常期待看到地图解决方案出现在这里!):
#!perl -l
我的%哈希=();
$hash{key1}{key2} = ['', '', '',];
对于我的 $outer (keys %hash) {
对于我的 $inner (keys $hash{$outer}) {
print join(', ', $outer, $inner, @{ $hash{$outer}{$inner} } )
输出:
键1、键2、、、
如果事情变得非常复杂,还有 Data::、Data::Seek、Data::Dive 和其他几个方便的模块。 有些需要使用散列引用,尽管这可能会使更简单的解决方案变得复杂,或者更有可能出现更大、更困难的问题......
干杯,