簡體   English   中英

如何更新哈希數組中的值,該數組位於 perl 的 hash 的 hash 中?

[英]How do I update values in an array of hashes, which is in a hash of a hash in perl?

我知道似乎很混亂。 我將嘗試“繪制”這個數據結構:

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

所以有第一個鍵,其值包含在括號中。 hash 的第一個鍵的值是兩個鍵,一個(右側)是另一個簡單的鍵值對。 另一個(左側)鍵的值是一個哈希數組。 我可以使用以下代碼行更新“正確”鍵、值對:

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

其中 $parts[1] 和 $parts[2] 只是數組中的元素。 我在我的 hash 的“正確”鍵、值對中 += 輸入一個數字。 我現在需要做的是更新“左”鍵、值對——散列 hash 中的散列數組。 以下是我為散列的 hash 中的兩個鍵值對初始化數組的方法:

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

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

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

我只是想不出正確的語法。 如果有人可以幫助我,我將不勝感激。 謝謝。

編輯:我想一個更尖銳的問題是:如何從散列數組中獲取 hash 鍵(請記住,該數組位於散列的 hash 中)?

編輯:將此添加到代碼中:

#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];
}

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

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;

Output:

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

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

我的建議是避免像來自壞社區的瘟疫惡魔這樣的結構。

人們最終遇到這種維護噩夢的原因之一是他們正在使用XML::Simple

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

您描述結構的方式對我來說有點難以理解,但是使用更簡單的示例結構可以訪問嵌入在其他結構中的數組引用:

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

下面,6 的值增加到 7:

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

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

我還沒有解碼你的結構。 但是,我將發表兩條評論:

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

  2. 研究使用 Object 定向 Perl 用於此結構。 它並不像聽起來那么可怕。 在 Perl 中,對象是為您處理臟活的子例程。 看看perldoc perlboot 這是我用來了解面向 object 的 Perl 是如何工作的。 您甚至不必創建一個完整的單獨模塊。 object 定義可以存在於相同的 Perl 腳本中。

使用 Object Oriented Perl 可以將混亂保持在主程序之外,並使維護程序更容易。 另外,如果你必須修改你的結構,你不必搜索你的整個代碼來找到所有需要改變的地方。 語法糖使您更容易看到您的結構將走向何方。

將此怪物與此面向 object 的怪物進行比較。 兩個程序都做同樣的事情。 我很久以前寫了第一個,發現它很難維護,所以我以面向 object 的風格從頭開始重寫它。 (如果有人想知道,它們是 Subversion 的預提交鈎子)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM