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

时间:2017-01-22 07:38:48

标签: arrays perl hash

我尝试对哈希值@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 "@sorted\n";

结果我想得到@sorted_aoh这样:

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

3 个答案:

答案 0 :(得分:2)

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

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

散列的标识已丢失,数据被展平为单个列表。 Perl使用 references

实现嵌套结构

你没有说出你的数据来自哪里,而是从一些单独命名的哈希开始然后将它们的引用复制到一个数组中,最好直接使用数组的元素,所以$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 => %d\n", $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

我希望您同意构建map的{​​{1}}语句简洁明了,但可能会让您感到困惑。如果你愿意,你可以写一个for循环而不是做同样的事情,比如这个

%desc_to_index

产生相同的结果

还要注意你的循环

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 ) { ... } ,这在这里是不常见且不必要的。它在Perl 5 v12之前也不可用,如果循环过早退出,each会产生尴尬的错误

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

for

答案 1 :(得分:1)

以下代码使用散列引用数组,并根据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);

答案 2 :(得分:-1)

如何在ll 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);