【问题标题】:different type of value for each key in a hash哈希中每个键的不同类型的值
【发布时间】:2013-01-19 13:01:18
【问题描述】:

我搜索了Google,但没有找到任何有用的东西。

尽管有很多 Perl 教程,但我没有找到任何教程会提到每个键都有不同值的哈希? 在 Perl 中这样的事情是可能的吗?

例如,是否有一个像这样有 2 个键(ab)的哈希,其中:

$myhash{"a"}=1;
$myhash{"b"}=[ 'hamnet', 'shakespeare', 'robyn', ];

以上可以吗?


我试过了:

#!/usr/bin/perl

use strict;
my %x;

$x{"a"}="b";
$x{"b"}=['c','d'];

foreach (keys %x)
{
  print $_."\n";
  print "$x{$_}";
}

但它正在输出:

a
bb
ARRAY(0x1ece50)

我对如何访问此哈希的元素感到困惑。

我想告诉你这一切,尽管我对 Perl 有点了解,但我在哈希方面完全是新手。


好的,我发现了一件事——要访问散列中的数组,我需要这样做:

@{$x{"b"}}

但是正如我已经告诉你的,哈希值可以是数组也可以是标量值,所以要访问上述哈希值,我需要先识别值的类型,然后再访问它!我怎样才能做到这一点? 也就是说,如何识别键的值是标量、数组还是散列?

【问题讨论】:

  • 输出看起来不错。你期待什么?

标签: perl hash


【解决方案1】:

“尽管有很多 Perl 教程,但我没有找到任何教程会提到每个键都有不同值的散列?在 Perl 中可以做到这一点吗?”

您可能已经尝试查看tutorials included in your Perl distribution,其中包括Perl Data Structures Cookbook (perldsc)。它包括关于"More Elaborate Records" 的一章,其中提供了有关如何创建和使用值具有不同类型的哈希的示例。

"但是我已经告诉过你,hash的值可以是数组也可以是标量值,所以要访问上面的hash,我需要先识别出值的类型,然后再访问它!怎么能我这样做?也就是说,如何识别键的值是标量、数组还是散列?"

由于您似乎不熟悉referencesref 运算符的用法,因此您可能还想看看Mark's very short tutorial about references (perlreftut)

请注意,所有这些教程(以及更多)已经随您的 Perl 发行版一起提供,您可以通过键入例如来访问它们

perldoc perlreftut

在命令行上。 (在某些系统上,您可能需要安装一个额外的包来启用perldoc 命令。如果您打算进行任何 Perl 编程,强烈建议您这样做。)

【讨论】:

    【解决方案2】:

    我认为这是你想要的:

     #!/usr/bin/perl -w
     use strict;
     my %x;
    
     $x{"a"}="b";
     $x{"b"}=['c','d'];
    
    
     foreach my $a (keys %x)
     {
         if ( ref $x{$a} eq 'ARRAY' )
         {
             foreach my $b ( @{ $x{$a} } )
             {
                 print $b."\n";
             }
         }
         else
         {
             print $x{$a}."\n";
         }
     }
    

    输出:

    # perl test.pl 
    b
    c
    d
    

    检查哈希值是否为“ARRAY”引用。如果是,则遍历数组并打印值。否则,立即打印哈希值。

    【讨论】:

      【解决方案3】:

      所以为了访问上面的哈希,我需要首先识别值的类型,然后访问它!我该怎么做?即,我如何确定键的值是否是单数、数组、散列?

      我认为一个干净的解决方案是编写一个简单的to_string 函数(不支持更深的嵌套结构),它识别值是标量、数组引用还是散列引用(这就是@987654324 @ 创建:对匿名数组的引用,参见 perlreftut)。阅读更多关于ref的信息。

      sub to_string {
          my $thing = shift;
      
          for (ref $thing) {
      
              # join with comma if $thing is an array ref
              return join ', ' => @$thing when 'ARRAY';
      
              # join key-value list with comma if $thing is a hash ref
              return join ', ' => map {"$_ => $thing->{$_}"} keys %$thing when 'HASH';
      
              # else: simply return the $thing itself
              return $thing;
          }
      }
      

      在一个简单的示例程序中

      my %data = (
          foo => 42,
          bar => [1, 2, 3],
          baz => {a => 'yay', b => 'nay'},
      );
      
      for my $key (keys %data) {
          say "$key: " . to_string($data{$key});
      }
      

      它会给你这个输出:

      bar: 1, 2, 3
      baz: a => yay, b => nay
      foo: 42
      

      请注意,您必须这样做

      use feature qw(say switch);
      

      对于这个程序。 HTH! :)

      【讨论】:

        猜你喜欢
        • 2011-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-04
        • 1970-01-01
        • 2020-07-18
        • 1970-01-01
        相关资源
        最近更新 更多