2010-08-07 184 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