Perl:for循环中的hash,在循环外是空的

时间:2015-11-27 20:40:03

标签: arrays perl hash

我了解HASH功能。使用“for”循环,我动态地创建哈希和“hashnames”,并且我用一些键/值元素来提供它们。不幸的是,这些值在循环外不再可见。 在我使用的小代码及其输出下面。

#!/usr/bin/perl -w

use warnings;
use English;
use Data::Dumper;

@wA = ("a", "b", "c", "d", "e", "f");
@dA = (1, 2, 3, 4, 5, 6);

for (my $i=0; $i<=$#wA; $i++){
    $hn = "hash-$wA[$i]";
    push(@hna, $hn);
    %hn = ();
    #my %hn;
    $hsize = @hn;
    print "1. HashName: " . $hn . " Size: " . $hsize . "\n";
    print "HashName: $hn\n";
    if ($i == 0){
        print "Feed the hash $hn: ";
        for (my $j=$i; $j<=$#dA; $j++){
            $hn{ $dA[$j] } = $wA[$j];
            print "$dA[$j] => $wA[$j], ";
        }
        print "\n";
    }
    if ($i == 1){
        print "Feed the hash $hn: ";
        for (my $j=$i; $j<=$#dA; $j++){
            $hn{ $dA[$j] } = $wA[$j];
            print "$dA[$j] => $wA[$j], ";
        }
        print "\n";
    }
    if ($i == 2){
        print "Feed the hash $hn: ";
        for (my $j=$i; $j<=$#dA; $j++){
            $hn{ $dA[$j] } = $wA[$j];
            print "$dA[$j] => $wA[$j], ";
        }
        print "\n";
    }
    if ($i == 3){
        print "Feed the hash $hn: ";
        for (my $j=$i; $j<=$#dA; $j++){
            $hn{ $dA[$j] } = $wA[$j];
            print "$dA[$j] => $wA[$j], ";
        }
        print "\n";
    }
    if ($i == 4){
        print "Feed the hash $hn: ";
        for (my $j=$i; $j<=$#dA; $j++){
            $hn{ $dA[$j] } = $wA[$j];
            print "$dA[$j] => $wA[$j], ";
        }
        print "\n";
    }
    if ($i == 5){
        print "Feed the hash $hn: ";
        for (my $j=$i; $j<=$#dA; $j++){
            $hn{ $dA[$j] } = $wA[$j];
            print "$dA[$j] => $wA[$j], ";
        }
        print "\n";
    }
    if ($i == 6){
        print "Feed the hash $hn: ";
        for (my $j=$i; $j<=$#dA; $j++){
            $hn{ $dA[$j] } = $wA[$j];
            print "$dA[$j] => $wA[$j], ";
        }
        print "\n";
    }
    @hk = keys %hn;
    $hsize = @hk;
    print "2. HashName: " . $hn . " Size: " . $hsize . "\n";
}

print "\n";
print "Araay with hashNames: " . @hna . " Array length: " . $#hna . "\n";
print "\n\n\n";

print "Hash info out of the FOR loop\n";

for (my $k=0; $k<=$#hna; $k++){
    @hnaca = keys %{$hna[$k]};
    #@hnaca = keys @{ @hna[$k] };
    #@hnaca = keys \%{ $hna[$k] };
    #@hnaca = keys %{ $hna->[$k] };
    print "Element: " . $k . " HashName: " . $hna[$k] . " Size(\$#): " . $#hnaca . " Size(\@): " . @hnaca . "\n";
}

输出如下:

1. HashName: hash-a Size: 0
HashName: hash-a
Feed the hash hash-a: 1 => a, 2 => b, 3 => c, 4 => d, 5 => e, 6 => f, 
2. HashName: hash-a Size: 6
Data::Dumper: 1. HashName: hash-b Size: 0
HashName: hash-b
Feed the hash hash-b: 2 => b, 3 => c, 4 => d, 5 => e, 6 => f, 
2. HashName: hash-b Size: 5
Data::Dumper: 1. HashName: hash-c Size: 0
HashName: hash-c
Feed the hash hash-c: 3 => c, 4 => d, 5 => e, 6 => f, 
2. HashName: hash-c Size: 4
Data::Dumper: 1. HashName: hash-d Size: 0
HashName: hash-d
Feed the hash hash-d: 4 => d, 5 => e, 6 => f, 
2. HashName: hash-d Size: 3
Data::Dumper: 1. HashName: hash-e Size: 0
HashName: hash-e
Feed the hash hash-e: 5 => e, 6 => f, 
2. HashName: hash-e Size: 2
Data::Dumper: 1. HashName: hash-f Size: 0
HashName: hash-f
Feed the hash hash-f: 6 => f, 
2. HashName: hash-f Size: 1
Data::Dumper: 
Araay with hashNames: 6 Array length: 5



Hash info out of the FOR loop
Element: 0 HashName: hash-a Size($#): -1 Size(@): 0 -> expected 5 / 6
Element: 1 HashName: hash-b Size($#): -1 Size(@): 0 -> expected 4 / 5
Element: 2 HashName: hash-c Size($#): -1 Size(@): 0 -> expected 3 / 4
Element: 3 HashName: hash-d Size($#): -1 Size(@): 0 -> expected 2 / 3
Element: 4 HashName: hash-e Size($#): -1 Size(@): 0 -> expected 1 / 2
Element: 5 HashName: hash-f Size($#): -1 Size(@): 0 -> expected 0 / 1

如何获得预期值?

2 个答案:

答案 0 :(得分:2)

奇怪的是,这就是你所追求的目标吗?:

use warnings;
use strict;

my @wA = qw(a b c d e f);
my @dA = qw(1 2 3 4 5 6);

my %hash;

for my $w (@wA){
    $hash{$w} = shift @dA;
}

...或使用迭代器(我们很少需要在Perl中使用迭代器)。请注意使用.. aka。触发器运算符或正式range运算符:

for my $i (0..$#wA){
    $hash{$wA[$i]} = $dA[$i];
}

......甚至更简洁一点(没有明确定义的迭代器):

for (0..$#wA){
    $hash{$wA[$_]} = $dA[$_];
}

...最后,你甚至可以最终得到这个(只要你预先检查了每个数组的长度):

for (@wA){
    $hash{$_} = shift @dA; # requires array length checks
}

......还有一个(@Borodin建议我忽略了),slice

@hash{@wa} = @dA

然后,在上述所有情况下,请使用Dumper或:

for my $key (keys %hash){
    print "$key: $hash{$key}\n";
}

答案 1 :(得分:1)

您的程序存在的问题是您根本没有保存哈希值。 push(@hna, $hn);将哈希的名称作为字符串推送到@hna。这是您为for外部保存的唯一变量。

如果同时保存名称和您在@hna中创建的哈希值:push(@hna, {name => $hn, hash => \%hn});,您将获得更多成功。

 @@ -9,9 +9,7 @@ use Data::Dumper;

  for (my $i=0; $i<=$#wA; $i++){
      $hn = "hash-$wA[$i]";
 -    push(@hna, $hn);
 -    %hn = ();
 -    #my %hn;
 +    my %hn = ();
      $hsize = @hn;
      print "1. HashName: " . $hn . " Size: " . $hsize . "\n";
      print "HashName: $hn\n";
 @@ -73,6 +71,7 @@ for (my $i=0; $i<=$#wA; $i++){
      }
      @hk = keys %hn;
      $hsize = @hk;
 +    push(@hna, {name => $hn, hash => \%hn});
      print "2. HashName: " . $hn . " Size: " . $hsize . "\n";
  }

 @@ -83,9 +82,9 @@ print "\n\n\n";
  print "Hash info out of the FOR loop\n";

  for (my $k=0; $k<=$#hna; $k++){
 -    @hnaca = keys %{$hna[$k]};
 +    @hnaca = keys %{$hna[$k]->{"hash"}};
      #@hnaca = keys @{ @hna[$k] };
      #@hnaca = keys \%{ $hna[$k] };
      #@hnaca = keys %{ $hna->[$k] };
 -    print "Element: " . $k . " HashName: " . $hna[$k] . " Size(\$#): " . $#hnaca . " Size(\@): " . @hnaca . "\n";
 +    print "Element: " . $k . " HashName: " . $hna[$k]->{"name"} . " Size(\$#): " . $#hnaca . " Size(\@): " . @hnaca . "\n";
  }

这提供了这个完整的程序,对我有用:

 #!/usr/bin/perl -w

 use warnings;
 use English;
 use Data::Dumper;

 @wA = ("a", "b", "c", "d", "e", "f");
 @dA = (1, 2, 3, 4, 5, 6);

 for (my $i=0; $i<=$#wA; $i++){
     $hn = "hash-$wA[$i]";
     my %hn = ();
     $hsize = @hn;
     print "1. HashName: " . $hn . " Size: " . $hsize . "\n";
     print "HashName: $hn\n";
     if ($i == 0){
         print "Feed the hash $hn: ";
         for (my $j=$i; $j<=$#dA; $j++){
             $hn{ $dA[$j] } = $wA[$j];
             print "$dA[$j] => $wA[$j], ";
         }
         print "\n";
     }
     if ($i == 1){
         print "Feed the hash $hn: ";
         for (my $j=$i; $j<=$#dA; $j++){
             $hn{ $dA[$j] } = $wA[$j];
             print "$dA[$j] => $wA[$j], ";
         }
         print "\n";
     }
     if ($i == 2){
         print "Feed the hash $hn: ";
         for (my $j=$i; $j<=$#dA; $j++){
             $hn{ $dA[$j] } = $wA[$j];
             print "$dA[$j] => $wA[$j], ";
         }
         print "\n";
     }
     if ($i == 3){
         print "Feed the hash $hn: ";
         for (my $j=$i; $j<=$#dA; $j++){
             $hn{ $dA[$j] } = $wA[$j];
             print "$dA[$j] => $wA[$j], ";
         }
         print "\n";
     }
     if ($i == 4){
         print "Feed the hash $hn: ";
         for (my $j=$i; $j<=$#dA; $j++){
             $hn{ $dA[$j] } = $wA[$j];
             print "$dA[$j] => $wA[$j], ";
         }
         print "\n";
     }
     if ($i == 5){
         print "Feed the hash $hn: ";
         for (my $j=$i; $j<=$#dA; $j++){
             $hn{ $dA[$j] } = $wA[$j];
             print "$dA[$j] => $wA[$j], ";
         }
         print "\n";
     }
     if ($i == 6){
         print "Feed the hash $hn: ";
         for (my $j=$i; $j<=$#dA; $j++){
             $hn{ $dA[$j] } = $wA[$j];
             print "$dA[$j] => $wA[$j], ";
         }
         print "\n";
     }
     @hk = keys %hn;
     $hsize = @hk;
     push(@hna, {name => $hn, hash => \%hn});
     print "2. HashName: " . $hn . " Size: " . $hsize . "\n";
 }

 print "\n";
 print "Araay with hashNames: " . @hna . " Array length: " . $#hna . "\n";
 print "\n\n\n";

 print "Hash info out of the FOR loop\n";

 for (my $k=0; $k<=$#hna; $k++){
     @hnaca = keys %{$hna[$k]->{"hash"}};
     #@hnaca = keys @{ @hna[$k] };
     #@hnaca = keys \%{ $hna[$k] };
     #@hnaca = keys %{ $hna->[$k] };
     print "Element: " . $k . " HashName: " . $hna[$k]->{"name"} . " Size(\$#): " . $#hnaca . " Size(\@): " . @hnaca . "\n";
 }