从数组元素包含的哈希值中查找数组元素



我正在尝试对一个哈希数组@aoh进行排序,目前我提取了某些键的值并对该列表进行排序。我从每个散列中提取密钥description的值。

现在,我希望能够识别数组的哪个元素对应于哈希元素的给定值。

我想我需要使用哈希引用,但如何做到呢?

我的代码示例在下面

#!/usr/bin/perl
use warnings;
use strict;
my %h1 = ('description', 'great one');
my %h2 = ('description', 'fool');
my %h3 = ('description', 'easy');
my %h4 = ('description', 'intermediate');
my %h5 = ('description', 'hard');
my %h6 = ('description', 'beauty');
my %h7 = ('description', 'dark');
my %h8 = ('description', 'yellow');
my %h9 = ('description', 'red');
my @aoh = ( %h1, %h2, %h3, %h4, %h5, %h6, %h7, %h8, %h9 );
my @vals;
while ( my ($index, $value) = each @aoh ) {
if ( $aoh[$index] ne 'description' ) {
push @vals, $aoh[$index];
}
}
my @sorted = sort @vals;
printf "@sortedn";

因此,我想得到这样的@sorted_aoh

@sorted_aoh = (
'description'->'beauty',
'description'->'dark',
'description'->'easy',
'description'->'fool',
'description'->'great one',
'description'->'one',
'description'->'hard',
'description'->'intermediate',
'description'->'red',
);

如前所述,您的数组@aoh不是哈希数组,它只是标量数据数组。看起来像这个

(
"description",
"great one",
"description",
"fool",
"description",
"easy",
"description",
"intermediate",
"description",
"hard",
"description",
"beauty",
"description",
"dark",
"description",
"yellow",
"description",
"red",
)

散列的标识已经丢失,数据被扁平化为一个列表。Perl通过使用引用实现嵌套结构

你没有说你的数据来自哪里,但与其从一些单独命名的散列开始,然后将它们的引用复制到一个数组中,最好直接使用数组的元素,这样$h1{description}就变成了$aoh[0]{description}等等。

这个解决方案从这样构建的@aoh开始,因此没有命名哈希。

(顺便说一句,像%h1@aoh这样的名称非常糟糕。标识符应该描述其内容的概念,所以%people@sales_figures,而不是它们本身的数据结构的性质。Perl语言中的前导%@无论如何都会告诉你这一点,但这同样适用于任何语言中的标识符。)

如果你经常发现自己需要访问程序中与另一个值对应的值,那么通常最好构建一个单独的哈希来存储这种关系。在这里,我构建了散列%desc_to_index,它将每个散列的description元素的值与找到的数组的索引联系起来

我在最后转储了生成的结构,这样你就可以看到它包含了什么

use strict;
use warnings 'all';
use List::Util 'max';
my @aoh = (
{ description => 'great one' },
{ description => 'fool' },
{ description => 'easy' },
{ description => 'intermediate' },
{ description => 'hard' },
{ description => 'beauty' },
{ description => 'dark' },
{ description => 'yellow' },
{ description => 'red' },
);
my %desc_to_index = map { $aoh[$_]{description} => $_ } 0 .. $#aoh;
{
my $len = max map { length } keys %desc_to_index;
for my $desc ( sort keys %desc_to_index ) {
printf "%*s => %dn", $len, $desc, $desc_to_index{$desc};
}
}

输出

beauty => 5
dark => 6
easy => 2
fool => 1
great one => 0
hard => 4
intermediate => 3
red => 8
yellow => 7

我希望您同意构建%desc_to_indexmap语句简洁明了,但它可能会让您感到困惑。如果你愿意,你可以写一个for循环,它做同样的事情,比如这个

my %desc_to_index;
for my $i ( 0 .. $#aoh ) {
my $desc = $aoh[$i]{description};
$desc_to_index{$desc} = $i;
}

其产生相同的结果

还请注意,您的环路

while ( my ($index, $value) = each @aoh ) { ... }

在数组上使用each,这在这里是不寻常的,也是不必要的。它在Perl5v12之前也不可用,如果循环过早退出,each可能会产生尴尬的错误

您不需要each,因为您从不使用$value的值,而是更喜欢$aoh[$index],这更常见。您的循环最好使用像这样的简单for循环来编写

for my $index ( 0 .. $#aoh ) { ... }

以下代码使用一个哈希引用数组,并根据description键的值对其进行排序。哈希变量名称(%h1)前的反斜杠表示对该哈希的引用。sort函数使用自定义比较块,查找perldoc -f sort以获取有关它的更多信息,并查找perldoc perlcheat以了解如何使用引用。

#!/usr/bin/perl
use warnings;
use strict;
my %h1 = ('description', 'greate one');
my %h2 = ('description', 'fool');
my %h3 = ('description', 'easy');
my %h4 = ('description', 'intermediate');
my %h5 = ('description', 'hard');
my %h6 = ('description', 'beauty');
my %h7 = ('description', 'dark');
my %h8 = ('description', 'yellow');
my %h9 = ('description', 'red');
my @aoh = (%h1, %h2, %h3, %h4, %h5, %h6, %h7, %h8, %h9);
my @sorted = sort { $a->{description} cmp $b->{description} } @aoh;
use Data::Dumper;
print Dumper(@sorted);

如何在所有hasesh 中利用唯一密钥名称

use Data::Dumper;
my %h1 = ('description', 'great one');
my %h2 = ('description', 'fool');
my %h3 = ('description', 'easy');
my %h4 = ('description', 'intermediate');
my %h5 = ('description', 'hard');
my %h6 = ('description', 'beauty');
my %h7 = ('description', 'dark');
my %h8 = ('description', 'yellow');
my %h9 = ('description', 'red');
my @aoh =  sort map { values $_ } (%h1, %h2, %h3, %h4, %h5, %h6, %h7, %h8, %h9);
my @hash = map { {"description" => $_}} @aoh;
print  Dumper(@hash);

最新更新