如何打印用作%hash值的@array的$元素?

Zes*_*Rex 2 arrays perl hash perl-data-structures

我认为对于有经验的人来说这应该很容易解决,对我来说虽然我在谷歌上尝试和搜索这个但是找不到适合我情况的东西.我只想让$ amountok和$ amountko给出它们在索引0和1处的值,但它不是这样的(参见#mark).

print ERGEBNIS "ID;Amount;Amount OK;Amount KO\n";
foreach my $key (keys %elementhash){
  my $sum = 0;              
  foreach $valueofkey(@{$elementhash{$key}}){                   
     $sum += $valueofkey;           
  }

  #my $amountok= @{$elementhash{$key}[0]};
  #my $amountko= @{$elementhash{$key}[1]};

  print ERGEBNIS $key.";".$sum.";".$amountok.";".$amountko."\n";

}
Run Code Online (Sandbox Code Playgroud)

这会让我错误:"不能使用字符串"7"作为数组引用.",这必须是可能的,但我只是不知道如何!感谢你们

这是%elementhash的Dumper输出:

 $VAR1 = {                '1000' => [7],               
                          '2000' => [5],                  
                          '3000' => [56, 12]              
         };                     
Run Code Online (Sandbox Code Playgroud)

sim*_*que 5

您的哈希元素包含数组引用.即使数组ref中只有一个值,它仍然是数组引用.您可以使用->运算符进行解除引用.

$elementhash{$key}->[0];
Run Code Online (Sandbox Code Playgroud)

请注意,您首先使用哈希,而不是哈希引用,因此在{$key}部件之前没有箭头.里面有一个数组引用.实际上,您并不需要->在前面放置一个,[0]因为Perl知道嵌套数据结构是从引用构建的.这是一个很好的讨论问题.我个人喜欢箭头,但这里不需要它1.

你尝试做的@{$elementhash{$key}[0]}是获取内部的第一个元素$key,例如7for键1000,并将其作为数组deref.当然你不能这样做,因为它是一个数字,而不是一个数组引用.

因为并非数据结构中的所有数组都有两个值,所以应检查第二个值是否存在.您可以使用//defined-or运算符执行此操作.它允许0或其他非真实值,但不允许undef.

最后,你错过my$valueofkey.

use strict;
use warnings;

my %elementhash = (
    '1000' => [7],
    '2000' => [5],
    '3000' => [ 56, 12 ]
);

print "ID;Amount;Amount OK;Amount KO\n";
foreach my $key ( keys %elementhash ) {
    my $sum = 0;
    foreach my $valueofkey ( @{ $elementhash{$key} } ) {
        $sum += $valueofkey;
    }

    my $amountok = $elementhash{$key}->[0];
    my $amountko = $elementhash{$key}->[1] // 0;

    print $key. ";" . $sum . ";" . $amountok . ";" . $amountko . "\n";
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可以重写要使用的最后一行join.

print join( ';', $key, $sum, $amountok, $amountko ),  "\n";
Run Code Online (Sandbox Code Playgroud)

如果你的Perl至少是版本5.10,你也可以打开,use feature 'say'这样你就不需要打印了"\n".

say join ';', $key, $sum, $amountok, $amountko;
Run Code Online (Sandbox Code Playgroud)

如果您有更复杂的CSV,请考虑使用Text :: CSVText :: CSV_XS.


1)如果您开始的变量是参考,则需要一个箭头.但是你可以省略以下几个.

my $foo = { bar => [1, 2, 3] };
say $foo->{bar}[2]; # works
say $foo{bar}[2]; # complains that %foo needs explicit package name
Run Code Online (Sandbox Code Playgroud)

  • @ZesaRex不这样做.始终对任何变量使用尽可能小的范围.特别是循环迭代器应始终是它们循环的词汇. (3认同)