2010-08-07 114 views
2

我有一个28个元素的数组。Perl哈希和数组

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

如果我尝试打印散列,它不显示所有的键和值。

代码如下给出

@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 

我想在阵列中的所有内容,以被复制到散列中并被打印,如果我尝试遍历散列。但是一些只有部分数组内容被复制到哈希中。

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

谢谢 Senthil。

+2

的问题是,有两组数据,与一个'name',后者覆盖前者开始。你希望你的散列与他们做什么?他们应该成为两个subhashes? – MvanGeest 2010-08-07 09:45:40

+0

看看perldsc(1) – ninjalj 2010-08-07 22:03:12

回答

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(); 
+0

好友感谢你的回答和回复... – 2010-08-09 05:25:46

6

您有多个具有相同名称的密钥,因此您正在覆盖数据。

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

可能你需要一个更聪明的算法来构造你的散列(例如把值放在数组ref中而不仅仅是一个简单的值)。可能你需要忘掉哈希,并且用一个for循环遍历整个数组,循环每次增加2。

+0

嗨,Mvan和David 感谢您的回复。问题与你所说的一样。我想用数组内容创建一个数据结构。条件是数组内容将以'name'开头。除了没有“名称”的数据之外,有什么办法可以解决这个问题?帮我看看。 – 2010-08-07 10:45:17

+0

你有一个数据结构(数组)。如果您需要不同的数据结构,那么您需要设计该数据结构,然后将数据放入其中。一个哈希键映射到一个值,只有一个值。因此,如果您的数据结构的设计涉及多个具有相同名称的密钥,那么一个简单的哈希将无法完成这项工作。我在答案中提出了一个备选方案。另一个将是一个hashrefs或arrayrefs数组。 – Quentin 2010-08-07 11:15:27

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

+0

好友谢谢你的回答和回复... – 2010-08-09 05:17:38

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' 
        ] 
     }; 
+0

伟大的答案男人...你花了我一段美好的时光..我会去你的方法 – 2010-08-09 05:26:43