为什么数组不能在以下perl脚本中保存哈希键?

时间:2016-05-20 05:14:57

标签: arrays perl

hash_test.pl

@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只是持有最后一个元素。

有人可以告诉我为什么或帮助我改进脚本吗?

2 个答案:

答案 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声明您的变量。这可以防止你犯这种错误。