【问题标题】:What does it mean to have a perl hash{}{}有一个 perl 哈希是什么意思{}{}
【发布时间】:2015-02-15 09:50:21
【问题描述】:

我的教授在幻灯片上有一些我不理解的语法。

在 perl 中有:

$hash{$string}{$anotherString}++;

这个语法是什么意思?如果是:

$hash{$string}{$int}++;

它会增加价值吗? 当我使用打印时

while( my( $key, $value ) = each %hash ){print "$key: $value\n";}

我的输出是 “密钥”:哈希(0xbe0200)

【问题讨论】:

  • 如果$hash{$string}{$anotherString} 是一个整数,那么$hash{$string}{$anotherString}++ 会增加它。有什么问题?
  • 你的输出是合理的。 $hash{$string} 是一个哈希值。它在索引$anotherString 处的值是一个整数,这行代码正在递增它。
  • 所以这只是键值对的另一种写法?
  • 如果写成$hash_of_hash{$string}{$another_string},也许代码会更清晰。这在文档中得到了很好的解释:perldoc perllol
  • 感谢这让我现在走上了正确的道路。

标签: perl hash


【解决方案1】:

那是一个二维散列,散列的散列。一旦您意识到任何单个值实际上都是标量,就很容易在 Perl 中跟踪结构。在多维结构的情况下,标量值是一个参考。例如:

my %outer = ( "foo" => { "bar" => 1 } );

内部{ "bar" => 1 } 是一个哈希引用。在赋值中使用{ } 表示匿名哈希。这类似于:

my %inner = ( "bar" => 1 );
my %outer = ( "foo" => \%inner );

现在,当您要引用%inner 中的值时,您可以使用第一个键访问哈希引用,使用第二个键访问%inner 中的值:

print $outer{"foo"}{"bar"};  # prints 1

当你在一个值上使用increment operator ++ 时,它会递增:

$outer{"foo"}{"bar"}++;      # the value is now 2

【讨论】:

    【解决方案2】:
    $hash{string1}{string2}
    

    是一个较短的等价物

    $hash{string1}->{string2}
    

    即它从散列的散列中返回一个值。

    通过应用++ 运算符,内部散列中的值递增。

    【讨论】:

      【解决方案3】:

      我的输出是“key”:HASH(0xbe0200)

      那个奇怪的输出意味着你要打印的实际上是一个哈希引用

      use strict; 
      use warnings; 
      use 5.016;  #allows you to use say(), which is equivalent to print() 
                  #plus a newline at the end
      
      my $href = {
          a => 1,
          b => 2,
      };
      
      say $href;
      
      --output:--
      HASH(0x100826698)
      

      或者,

      my %hash = (
          a => 1,
          b => 2,
      );
      
      say \%hash;
      
      --output:--
      HASH(0x1008270a0)
      

      \ 运算符获取其右侧事物的引用

      打印实际哈希的最简单方法是使用 Data::Dumper,这是您可以并且将一直使用的东西:

      use strict; 
      use warnings; 
      use 5.016;
      use Data::Dumper;
      
      my $href = {
          a => 1,
          b => 2,
      };
      
      
      say Dumper($href);
      
      $VAR1 = {
                'a' => 1,
                'b' => 2
              };
      

      use warnings; 一样,我认为use Data::Dumper; 对于每个程序都是强制性的。

      因此,当您看到奇怪的输出时,例如 HASH(0xbe0200),请在值上使用 Data::Dumper:

      my %hash = (
          a => 1,
          b => { hello => 2, goodbye => 3},
      );
      
      while( my( $key, $value ) = each %hash ){
          say $key;
          say Dumper($value);
          say '-' x 10;
      }
      
      --output:--
      a
      $VAR1 = 1;
      
      ----------
      b
      $VAR1 = {
                'hello' => 2,
                'goodbye' => 3
              };
      
      ----------
      

      或者,也可以在整个结构上使用 Data::Dumper:

      my %hash = (
          a => 1,
          b => { hello => 2, goodbye => 3},
      );
      
      
      say Dumper(\%hash);
      
      --output:--
      $VAR1 = {
                'a' => 1,
                'b' => {
                         'hello' => 2,
                         'goodbye' => 3
                       }
              };
      

      请注意 Dumper() 用于显示哈希引用(或任何其他引用)的内容,因此如果您的变量不是引用,例如%hash,那么您必须使用 \ 运算符将其转换为引用,例如\%hash.

      现在,如果你有这个哈希:

      my %hash = (
          a => 1,
          b => { hello => 2, goodbye => 3},
      );
      

      ...检索'goodbye'对应的值,可以这样写:

      say $hash{b}{goodbye};  #=>3
      

      $hash{b} 返回哈希(引用){ hello => 2, goodbye => 3},您可以使用下标{hello}{goodbye} 从该哈希中检索值。

      或者,您可以这样写:

      my %hash = (
          a => 1,
          b => { hello => 2, goodbye => 3},
      );
      
      my $string = 'b';
      my $anotherString = 'goodbye';
      
      say $hash{$string}{$anotherString};  #=>3
      

      并且要在哈希中增加值 3,您可以这样写:

      my $result = $hash{$string}{$anotherString}++;
      say $result;  #=>3
      say $hash{$string}{$anotherString};  #=>4
      

      postfix ++ 操作符实际上是在当前操作之后 递增值,所以 $result 为 3,然后哈希中的值递增为 4,如下所示:

      my $temp = $hash{$string}{$anotherString};
      $hash{$string}{$anotherString} = $hash{$string}{$anotherString} + 1;
      my $result = $temp;
      

      如果您希望增量发生在当前操作之前,那么您可以使用prefix ++ 运算符:

      my $result = ++$hash{$string}{$anotherString};
      say $result;  #=>4
      say $hash{$string}{$anotherString}; #=>4
      

      最后,如果$hash{$string}{$anotherString} 处的值不是数字,例如'green',你会得到一些奇怪的东西:

      my %hash = (
          a => 1,
          b => { hello => 2, goodbye => 'green'},
      );
      
      my $string = 'b';
      my $anotherString = 'goodbye';
      
      my $result = $hash{$string}{$anotherString}++;
      say $hash{$string}{$anotherString};
      
      --output:--
      greeo
      

      perl 有一个概念,即字符串 'green' 之后的字符串是字符串 'greeo',因为字母 'o' 出现在字母表中的字母 'n' 之后。如果您增加的字符串是“greez”,则输出将是:

        greez  original
        grefa  output
      

      “z”之后的下一个字母以“a”重新开始,但就像当您将 9 增加 1 并得到 10 时,“z”的增量会延续到左侧的列,从而增加该字母1,产生'f'。哈!

      【讨论】:

        猜你喜欢
        • 2012-05-12
        • 2014-02-24
        • 2015-10-12
        • 2016-11-07
        • 1970-01-01
        • 2013-04-08
        • 2018-03-05
        • 2020-05-21
        • 1970-01-01
        相关资源
        最近更新 更多