切片散列哈希perl

时间:2013-08-08 18:48:15

标签: perl multidimensional-array slice hash

我在我的程序中使用散列哈希。我想在同一行中将两个值相加。 我的哈希示例是:

%data_final = (
   2010 => { 
      Jan => {
        group1 => {
           Type1 => {
              Total1 => 12,
              Total2 => 10
           },
           Type2 => {
              Total1 => 17,
              Total2 => 14
           },
       },
     },
   }
);

我希望group1的Total1和Total2总计很大。我正在做以下事情:

$total1_sum = sum( @{$data_final}{2010}{Jan}{group1}}{qw/Type1 Type2}{Total1} );
$total2_sum = sum( @{$data_final}{2010}{Jan}{group1}}{qw/Type1 Type2}{Total2} );

$ total1_sum的输出应为29,$ total2_sum应为24, 但我在“} {”附近有语法错误。

非常感谢你的帮助。

4 个答案:

答案 0 :(得分:5)

@h{@k}{Total1}毫无意义。您的意思是迭代切片返回的每个引用并获取引用的哈希元素的值,但您忽略了使用任何形式的循环。 map在这里很方便。

应用map并修复错误的}后,您会得到:

my $total1_sum = sum map $_->{Total1},
   @{ $data_final{2010}{Jan}{group1} }{qw( Type1 Type2 )};
my $total2_sum = sum map $_->{Total2},
   @{ $data_final{2010}{Jan}{group1} }{qw( Type1 Type2 )};

让我们分解出公共位:

my @results = @{ $data_final{2010}{Jan}{group1} }{qw( Type1 Type2 )};
my $total1_sum = sum map $_->{Total1}, @results;
my $total2_sum = sum map $_->{Total2}, @results;

答案 1 :(得分:2)

试试这个代码就可以了:

#!/usr/bin/perl  

use strict; use warnings;  

my %data_final = (
   2010 => {
      Jan => {
        group1 => {
           Type1 => {
              Total1 => 12,
              Total2 => 10
           },
           Type2 => {
              Total1 => 17,
              Total2 => 14
           },
       },
     },
   }
);

my $total1_sum;
$total1_sum += $data_final{2010}{Jan}{group1}{$_}{Total1}
    for keys $data_final{2010}{Jan}{group1};

my $total2_sum;
$total2_sum += $data_final{2010}{Jan}{group1}{$_}{Total2}
    for keys $data_final{2010}{Jan}{group1};

print <<EOF;
total1_sum=$total1_sum
total2_sum=$total2_sum
EOF

输出

total1_sum=29
total2_sum=24

答案 2 :(得分:1)

在您的代码中发现了几个问题:

$total1_sum = sum( @{$data_final}{2010}{Jan}{group1}}{qw/Type1 Type2}{Total1} );
                                ^ extra }                           ^ missing /

此外,切片返回一个hashrefs列表,您无法直接访问该列表,因此需要将{Total1}部分更改为map(或循环)。

最终更正的代码:

$total1_sum = sum( map { $_->{Total1} } @{$data_final{2010}{Jan}{group1}}{qw/Type1 Type2/} );
$total2_sum = sum( map { $_->{Total2} } @{$data_final{2010}{Jan}{group1}}{qw/Type1 Type2/} );

答案 3 :(得分:0)

多个问题。

  1. 您错过了 qw 的终结符(您需要{qw/Type1 Type2/})。我认为这部分只是一种疏忽。
  2. $ data_final 之后不应该有} 。例如,如果您只想获得2010键的值,则为$data_final{2010},而不是{$data_final}{2010}。然后,要获取该值中包含的哈希中的键的值,请将另一个下标添加到该值:$data_final{2010}{Jan} ...依此类推。因此,您的哈希切片应为@{$data_final{2010}{Jan}{group1}}{qw/Type1 Type2/}
  3. 哈希切片返回一个数组,如 @ 暗示(实际上是必需的)。此特定散列片返回的数组确实包含散列,但您不能只将散列下标添加到散列数组中,以获取每个散列中相应键的值的数组。例如,如果您有一个包含哈希值的数组 @harray ,则@harray{mykey}将不会在每个哈希中返回 mykey 值的数组。但这就是你最后要对{Total1}{Total2}进行的尝试。因此,您需要做的是迭代哈希切片并总结给定键的值。
  4. 可能有更简洁的方法,但这有效:

    foreach (@{$data_final{2010}{Jan}{group1}}{qw/Type1 Type2/}) {
      $total1_sum += $$_{Total1};
    }
    foreach (@{$data_final{2010}{Jan}{group1}}{qw/Type1 Type2/}) {
      $total2_sum += $$_{Total2};
    }
    

    $$ 是取消引用,因为数组的元素实际上是哈希引用。