2011-04-29 161 views
2

我知道似乎很混亂。我試圖「畫出」這個數據結構:如何更新散列數組中的值,該散列值位於perl中散列的散列中?

hash-> key - >((key) - > [(key,value),(key,value),(key,value)... ], (key,value))

所以有第一個關鍵字,它的值被括在圓括號中。散列的第一個鍵的值是兩個鍵,一個(右邊的)是另一個簡單的鍵,值對。另一個(左邊的)鍵值是散列數組。我能夠使用以下行的代碼來更新「右」鍵,值對:

$hash{$parts[1]}{"PAGES"} += $parts[2]; 

其中$份[1]和$份[2]是從數組只是元素。我+ =從我的哈希值的「右」鍵值對。我現在需要做的是更新「左」鍵,值對 - 散列哈希中的散列數組。這是我如何初始化這兩個鍵,值對數組中的哈希散列:

$hash{$printer}{"PAGES"} = 0; 
$hash{$printer}{"USERS"} = [@tmp]; 

這是我多次嘗試哈希值的數組中訪問和更新的值之一:

$hash{$parts[1]}{"USERS"}[$parts[0]] += $parts[2]; 

我只是無法弄清楚這個正確的語法。如果有人可以幫助我,我會很感激。謝謝。

編輯:我猜一個更尖銳的問題是:我如何從哈希數組中獲得哈希鍵(記住數組是散列哈希)?

編輯:將此添加到代碼:

#Go through each user to check to see which user did a print job and add the page 
#count to their total 
#$parts[0] is the user name, $parts[1] is the printer name, $parts[2] is the page 
#count for the current print job 
for(my $i=0;$i<$arr_size;$i++) 
{ 
    my $inner = $hash{$parts[1]}{"USERS"}[$i]; 
    my @hash_arr = keys %$inner; 
    my $key = $hash_arr[0]; 

    #problem line - need to compare the actual key with $parts[0] 
    #(not the key's value which is a number) 
    if($hash{$parts[1]}{"USERS"}[$i]{$key} eq $parts[0]) 
    { 
     $hash{$parts[1]}{"USERS"}[$i]{$parts[0]} += $parts[2]; 
    } 
} 

編輯:哎呦嘿嘿,這是我需要的。它仍然不是那裏,但這是我正在尋找的種類:

if($key eq $parts[0]) 
{ 
    $hash{$parts[1]}{"USERS"}[$i]{$parts[0]} += $parts[2]; 
} 

回答

1

編輯以迴應編輯的問題:如何從散列數組中獲取散列鍵(請記住該數組位於散列散列中)。

use strict; 
use warnings; 

my %h; 
$h{printer}{PAGES} = 0; 
$h{printer}{USERS} = [ 
    {a => 1, b => 2}, 
    {c => 3, d => 4}, 
    {e => 5, f => 6}, 
]; 

# Access a particular element. 
$h{printer}{USERS}[0]{a} += 100; 

# Access one of the inner hashes. 
my $inner = $h{printer}{USERS}[1]; 
$inner->{$_} += 1000 for keys %$inner; 

# Ditto, but without the convenience variable. 
$h{printer}{USERS}[2]{$_} += 9000 for keys %{ $h{printer}{USERS}[2] }; 

use Data::Dumper qw(Dumper); 
print Dumper \%h; 

輸出:

$VAR1 = { 
    'printer' => { 
      'PAGES' => 0, 
      'USERS' => [ 
        { 
        'a' => 101, 
        'b' => 2 
        }, 
        { 
        'c' => 1003, 
        'd' => 1004 
        }, 
        { 
        'e' => 9005, 
        'f' => 9006 
        } 
        ] 
      } 
    }; 
+0

是的,我使用Data :: Dumper來查看值,並且我得到所有0的地方應該有1或4等。 – 2011-04-29 13:20:49

+0

這幾乎就是我想要做的,只是使用散列而不是數字(即使用其中一個散列元素的鍵作爲數組索引來獲取其相應的值並對其進行操作)。 – 2011-04-29 14:16:40

+0

@john史密斯不知道我跟着你,但看到編輯的迴應。 – FMc 2011-04-29 17:13:08

0

我無法理解您的描述結構。

我的建議是避免像壞鄰居那樣的結構惡化的結構。

人們最終做出這種維修噩夢的一個原因是他們使用XML::Simple

無論您的示例中出現什麼原因,請自己幫忙,並防止可怕的數據結構被創建。總是有替代品。如果你描述這個問題,人們將能夠提出一些建議。

+0

我想出了很多思考和討論之後這個數據結構。我需要跟蹤由17臺打印機中每臺打印機打印的頁面數以及這些打印機上打印的用戶數量。我從解析系統日誌中獲取此信息以瞭解打印事件。打印事件日誌中的每一行都包含用戶,打印機和打印頁數。因此,我創建這與打印的頁面,並且其值是「用戶名,打印頁數」鍵和值的對的陣列的「用戶」鍵每個打印機相關聯。 – 2011-04-29 13:19:32

+0

我尊重在這樣的數據結構的到達的努力。去過也做過。 (很久以前)。智慧仍然是爲了避免這樣的結構,因爲你爲什麼要在這裏發佈。這很難保持,而且很脆弱。會有變化,然後你會再次努力去理解你的數據結構。 - 使用對象([Moose](http://search.cpan.org/dist/Moose/)),使用XML和XPath,或使用SQL。後兩個聽起來像是過度殺傷,所以我會選擇#1,這應該是最簡單的。 – Lumi 2011-04-29 13:27:42

0

你所描述的結構的方式是有點動搖不了我,但是嵌入其他結構中訪問數組引用正是如此做,用簡單的例子結構:

my $ref = {k => [1, 3, 5, 6, 9]}; 

下面,6的值被遞增到7:

$ref->{k}->[3] += 1; 

有關->運算符的更多詳細信息,請參見perlref,但簡而言之,箭頭左側的表達式可以是任何返回引用的表達式。在某些情況下,運營商->是可選的,但它是最好的留在了清晰度。

0

我還沒有解碼的結構。但是,我要發表兩點意見:

  1. 使用->語法糖。例如,$hash->{key}->[2]->{key}比嘗試解析沒有語法糖的事情要清楚一點:${{hash}{key}}[1]{key}(如果這甚至是正確的...)

  2. 使用面向對象Perl查看此結構。這聽起來並不像可怕。在Perl中,對象是可以爲你處理骯髒工作的子例程。看看perldoc perlboot。這是我用來理解面向對象的Perl如何工作的。你甚至不需要創建一個完整的獨立模塊。對象定義可以存在於同一個Perl腳本中。面向Perl的

使用對象保持混亂的主程序以外,並使其更容易維護程序。另外,如果您必須修改結構,則無需搜索整個代碼即可找到要更改的所有位置。通過語法糖,您可以更輕鬆地查看結構的位置。

比較這monstrosity這個object oriented monstrosity。兩個程序都做同樣的事情。我很早以前就寫了第一篇文章,並且發現很難保證我以面向對象的風格從頭開始重寫它。 (如果有人想知道,他們是Subversion的預先提交鉤子)。

+0

感謝您的建議,但我所做的工作。也許它是comp。 SCI。我從高中畢業的學生,​​但我想嘗試創建一個適合我的場景的獨特數據結構。我認爲這是我的老闆在產出方面所追求的。謝謝大家。 – 2011-04-29 20:48:33

+0

@john smith - 「獨特」數據結構沒有錯。我建議的語法糖只是簡單地理解一下哪裏會發生什麼。這是散列數組的哈希,還是這是一個包含數組哈希的散列?語法糖只有幫助。 OO Perl是處理這些複雜結構的最好方法。你在一個地方隔離他們的訪問。而且,良好的面向對象編程技術使得它明顯體現了你的結構代表。我在Perl中編寫OO的90%是爲了一次性的事情。我永遠不會再使用它。但是,我的程序更容易維護。 – 2011-05-02 17:54:19