@a=("f","a","b");
$K{"f"}{"aa"}=1;
$K{"a"}{"aa"}=1;
$k{"b"}{"bb"}=1;
foreach(@a){
@c= sort keys %{$k{$_}};
}
print "@c\n";
foreach(@c) {...}
perl hash_test.pl
bb
我想将哈希的键保存到数组中,以便我可以将该数组用作以下语句的输入。
但似乎化验@c
只是持有最后一个元素。
有人可以告诉我为什么或帮助我改进脚本吗?
答案 0 :(得分:5)
您每次都会在foreach
中分配数组,因此每次都会覆盖它。所以你最终只分配了最后一件东西。如果您在print
内移动foreach
,您会发现它们都在那里。
要存储您需要将它们添加到数组中的那些键,而不是分配数组。我已将错误$k
更正为$K
,并将aa
更改为f
更改为ff
(期望它也是拼写错误)。
my @c;
foreach my $el (@a) {
push @c, sort keys %{$K{$el}};
}
print "@c\n";
这将打印行:ff aa bb
。每次通过循环时,在特定数组元素的散列中找到的所有键都被添加到@c
,每个键都作为一个单独的元素。因此@c
将包含整个数据结构中的所有底层关键字。
但是,我想提出更多建议。
始终 use strict;
和use warnings;
这不是迂腐,但直接有帮助。没有它我永远不会写代码。例如,错字会在这里被捕获。
使用描述性变量名称。具体来说,单字母变量名称太容易混淆,除非在非常短的循环中或它清楚地表明它们是什么。 (例如,像这样的拼写错误实际上并不会发生。)最重要的是,代码可以更好地使用。这通常会产生更好的代码。
请使用良好的压痕和间距。它在很多方面都有很大帮助。
嵌套数据结构的一个有用的包是Data::Dumper
,它可以打印整个格式很好的东西,所以我们可以看到它。尝试添加到代码的末尾
use Data::Dumper;
print Dumper(\%K);
这是一个核心模块,无需安装。还有其他人做同样或类似的事情。
这是另一种做你要求的方式。
my @lowest_keys = map { sort keys %{$K{$_}} } @a;
我称之为lowest_keys
,强调这些是数据结构中最后一个哈希值的底部。 map
依次将{ ... }
块中的处理应用于@a
的每个元素,并返回包含所有这些结果的列表。 (如果任何一个结果本身是一个列表,其元素多于一个,它会合并到整个输出列表中。所以这可能会创建输出列表,其中包含的元素比输入多得多。)这个<然后可以将em> list 分配给一个数组,如上所述,或者传递给另一个需要列表作为输入的函数。
map
通常用于将数组转换为另一个数组,方法是对{ ... }
块中的每个元素执行操作。它的近亲是grep
,用于过滤,只通过输入列表中{ ... }
的条件求值为true的元素,从而形成输出列表。例如,过滤掉未定义的数组元素:my @good = grep { defined } @all
答案 1 :(得分:3)
变量名称区分大小写,因此%K ...和%k ...不相同。 始终使用
use strict;
use warnings;
并使用my
声明您的变量。这可以防止你犯这种错误。