Perl哈希和数组

时间:2010-08-07 09:43:05

标签: perl hash

我有一个包含28个元素的数组。

我将数组内容复制到哈希。

如果我尝试打印哈希,则不会显示所有键和值。

代码如下,

@new;
%hash = @new;
foreach $food (keys %hash) 
{
 $color = $hash{$food};
 print "$food is $color.\n";
}

输出是::

attribute is Mandatory.
min is 0X00.
value is 778.
max is 9940486857.
name is Security_header.
type is nibble.

数组@new内容是,

name Protocol_discriminator attribute Mandatory value 778 min 0X00 max 994048685 value 7 min 0 max F name Security_header attribute Mandatory type nibble value 778 min 0X00 max 9940486857

如果我尝试遍历散列,我希望将数组的所有内容复制到散列中并进行打印。但是有些如何只将部分数组内容复制到哈希中。

任何人都可以帮助克服这个问题。我在过去两天都在挣扎。

由于 塞特希。

4 个答案:

答案 0 :(得分:6)

您有多个具有相同名称的键,因此您将覆盖数据。

您需要重新考虑您的方法。

可能你需要一个更智能的算法来构造你的哈希(例如,将值放在数组ref而不仅仅是一个简单的值)。可能你需要忘记哈希,只需使用for循环遍历数组,每次循环增加2。

答案 1 :(得分:6)

让我们更改@new的演示文稿以显示正在发生的事情:

my @new = qw/
  attribute Mandatory
  attribute Mandatory
  max       994048685
  max       9940486857
  max       F
  min       0
  min       0X00
  min       0X00
  name      Protocol_discriminator
  name      Security_header
  type      nibble
  value     7
  value     778
  value     778
/;

Perl哈希键是唯一的,因此在将@new分配给%hash时,给定键的最后一个值“获胜”。对于一个简单的示例

$ perl -le '%h = qw/1 a 1 b 1 c/; print $h{1}'
c

假设您有相同密钥的许多值,请使用可以处理它的数据结构:

my %hash;
for (my $i = 0; $i < @new; $i += 2) {
  my($name,$val) = @new[$i,$i+1];
  push @{ $hash{$name} } => $val;
}

如果你不介意销毁@new,代码可能会更加惯用:

while (@new) {
  my($name,$val) = splice @new, 0, 2;
  push @{ $hash{$name} } => $val;
}

这意味着与%hash中给定键相关联的每个值都是一个值数组的引用push运算符需要数组而不是引用,因此我们使用@{ ... }取消引用它。

如果您不熟悉Perl参考,请务必阅读perlrefperllol文档。

%hash中打印值的一种方法是

foreach my $name (sort keys %hash) {
  print "$name = [@{ $hash{$name} }]\n";
}

输出:

attribute = [Mandatory Mandatory]
max = [994048685 9940486857 F]
min = [0 0X00 0X00]
name = [Protocol_discriminator Security_header]
type = [nibble]
value = [7 778 778]

打印和调试复杂数据结构的另一个方便技巧是Data::Dumper模块:

use Data::Dumper;
print Dumper \%hash;

打印

$VAR1 = {
          'attribute' => [
                           'Mandatory',
                           'Mandatory'
                         ],
          'value' => [
                       '7',
                       '778',
                       '778'
                     ],
          'min' => [
                     '0',
                     '0X00',
                     '0X00'
                   ],
          'name' => [
                      'Protocol_discriminator',
                      'Security_header'
                    ],
          'max' => [
                     '994048685',
                     '9940486857',
                     'F'
                   ],
          'type' => [
                      'nibble'
                    ]
        };

答案 2 :(得分:2)

@new数组中的信息表明您需要更丰富的数据结构。我不知道你的问题的细节,但这是我看到的结构。

my @data = (
    # Each data item is a hash reference, with four
    # possible keys: name, attribute, type, and vals.
    # I added the 'vals' key to handle the other information.
    {
        name      => 'Protocol_discriminator',
        attribute => 'Mandatory',
        type      => undef,
        # The 'vals' key points to an array reference.
        # That array contains a list of hash references.
        vals => [
            { value => 778, min => '0X00', max => 994048685 },
            { value =>   7, min =>      0, max =>       'F' },
        ],
    },

    # Another data item.
    {
        name      => 'Security_header',
        attribute => 'Mandatory',
        type      => 'nibble',
        vals => [
            { value => 778, min => '0X00', max => 9940486857 },
        ],
    },
);

要了解如何使用复杂的数据结构,请参阅perlreftutperldscperllol

此外,您的脚本应始终包含use strictuse warnings

答案 3 :(得分:1)

简单答案:哈希应该被认为是一个关联数组 有一个唯一键,每个键都有一个值(可以是哈希)。

您的问题:每次遇到已存在的密钥时,您都要替换该值。


解决方案:

#!/usr/bin/perl -w    

use strict;   

   sub main{ 
      $" = ", ";                                         # format array output

      my %hash;   
      my @arr   =  ( ['color' ,'red' ]
                   , ['color' ,'blue']
                   , ['size'  ,'1'   ]
                   , ['size'  ,'2'   ] 
                   );

      foreach my $rcd (@arr) {
         push @{$hash{$$rcd[0]}} , $$rcd[1];
      }          

      print "@{$hash{color}} \n";                        # prints: red, blue
   }    

   main();