繁体   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