迭代嵌套的哈希perl

时间:2015-12-08 16:10:27

标签: perl hash

我有以下perl格式:

  my $categories = {
          category =>  {
                         {  id    =>  1,
                            name  =>  "pizza"},
                         {  id    =>  2,
                            name  =>  "pizza special"},
                         {  id    =>  3,
                            name  =>  "pasta"},
                         {  id    =>  4,
                            name  =>  "burgers"},
                         {  id    =>  5,
                            name  =>  "club sandwich"}
                      }
};

我想要实现的是迭代上面的perl格式并获取类别中每个哈希的id和名称。 我试图做的是:

foreach ( $categories->{category} ) {
              $Response->write(qq[
                      <div class="row text-center">
                          <div class="col-xs-4">$_->{id}</div>
                          <div class="col-xs-8">$_->{name}</div>
                      </div>
              ]);
        } 

但这并没有在屏幕上产生任何结果。任何人都可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

您列出的数据结构将无法按您的意图运行。它是您在创建问题时出现的复制/粘贴错误,或是您手动创建并犯了错误。

  my $categories = {
          category =>  {
                         {  id    =>  1,
                            name  =>  "pizza"},
                         {  id    =>  2,
                            name  =>  "pizza special"},
                         {  id    =>  3,
                            name  =>  "pasta"},
                         {  id    =>  4,
                            name  =>  "burgers"},
                         {  id    =>  5,
                            name  =>  "club sandwich"}
                      }
};

use Data::Printer;
p $categories;

__END__

Odd number of elements in anonymous hash at /home/foo/code/scratch.pl line 438.
\ {
    category   {
        HASH(0x1aa6148)   {
            id     2,
            name   "pizza special"
        },
        HASH(0x1ab9920)   {
            id     4,
            name   "burgers"
        },
        HASH(0x1acfbd8)   undef
    }
}

如您所见,您正在使用哈希引用作为哈希引用中的键。

use strict;
use warnings;
my $categories = {
    category =>  {
        {  id    =>  1, name  =>  "pizza"}, # key
        {  id    =>  2, name  =>  "pizza special"}, # value
        {  id    =>  3, name  =>  "pasta"}, # key
        {  id    =>  4, name  =>  "burgers"}, # value
        {  id    =>  5, name  =>  "club sandwich"} # key
        # BOOM! Odd number of elements
    }
};

这可能不是你想要的。

您需要做的是使用数组引用作为食物列表。

my $categories = {
    category =>  [
        {  id    =>  1, name  =>  "pizza"},
        {  id    =>  2, name  =>  "pizza special"},
        {  id    =>  3, name  =>  "pasta"},
        {  id    =>  4, name  =>  "burgers"},
        {  id    =>  5, name  =>  "club sandwich"}
    ]
};

现在您可以使用此代码来创建输出。为了演示,我用简单的print替换了你的对象方法调用。

foreach my $category ( @{ $categories->{category} } ) {
    print <<"HTML";
<div class="row text-center">
    <div class="col-xs-4">$category->{id}</div>
    <div class="col-xs-8">$category->{name}</div>
</div>
HTML
}

因为您现在有一个数组引用,所以需要使用@{ ... }语法取消引用它。

有关引用如何在Perl中工作的详细信息,请参阅perlrefperlreftut

答案 1 :(得分:1)

您已经错误地构建了哈希,如果您使用Data :: Dumper检查哈希,您会看到:

my $categories = {
   category => {
      {  id   => 1,
         name => "pizza"
      },
      {  id   => 2,
         name => "pizza special"
      },
      {  id   => 3,
         name => "pasta"
      },
      {  id   => 4,
         name => "burgers"
      },
      {  id   => 5,
         name => "club sandwich"
      }
   }
};
use Data::Dumper;
print Dumper $categories;

$VAR1 = {
          'category' => {
                          'HASH(0x7ff7746d3850)' => {
                                                      'name' => 'burgers',
                                                      'id' => 4
                                                    },
                          'HASH(0x7ff7746e1bc8)' => undef,
                          'HASH(0x7ff7746bee18)' => {
                                                      'name' => 'pizza special',
                                                      'id' => 2
                                                    }
                        }
        };

如您所见,由于您没有为内部哈希提供密钥,因此它使用前一个哈希的字符串化值作为密钥。我认为您可能打算使$categories->{category}和arrayref看起来像这样:

my $categories = {
   category => [
      {  id   => 1,
         name => "pizza"
      },
      {  id   => 2,
         name => "pizza special"
      },
      {  id   => 3,
         name => "pasta"
      },
      {  id   => 4,
         name => "burgers"
      },
      {  id   => 5,
         name => "club sandwich"
      },
   ],
};

可以像这样迭代:

foreach my $elem ( @{ $categories->{category} } ) {
   my ($id, $name) = map { $elem->{$_} } qw(id name);
   ...
}

答案 2 :(得分:1)

首先关闭 - 您的数据结构错误。应该是:

#!/usr/bin/env perl

use strict;
use warnings;
my $categories = {
    category => [
        {   id   => 1,
            name => "pizza"
        },
        {   id   => 2,
            name => "pizza special"
        },
        {   id   => 3,
            name => "pasta"
        },
        {   id   => 4,
            name => "burgers"
        },
        {   id   => 5,
            name => "club sandwich"
        }
    ]
};

foreach my $hash_ref ( @{ $categories->{category} } ) {
    print qq[
                      <div class="row text-center">
                          <div class="col-xs-4">$hash_ref->{id}</div>
                          <div class="col-xs-8">$hash_ref->{name}</div>
                      </div>
              ];
}

或者:

my $categories = {
    category => {
        1 => "pizza",
        2 => "pizza special",
        3 => "pasta",
        4 => "burgers",
        5 => "club sandwich",
    }
};

foreach my $key (  sort keys %{$categories->{category}} ) { 
    print qq[
                      <div class="row text-center">
                          <div class="col-xs-4">$key</div>
                          <div class="col-xs-8">$categories->{category}->{$key}</div>
                      </div>
              ];
}

启用use strict;use warnings;可以让您知道:

  

第5行的匿名哈希中奇数个元素。