哈希中每个键的不同类型的值

Posted

技术标签:

【中文标题】哈希中每个键的不同类型的值【英文标题】: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"

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

【问题讨论】:

输出看起来不错。你期待什么? 【参考方案1】:

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

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

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

由于您似乎不熟悉references 和ref 运算符的用法,因此您可能还想看看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! :)

【讨论】:

以上是关于哈希中每个键的不同类型的值的主要内容,如果未能解决你的问题,请参考以下文章

哈希表

第7章

汇总所有相似哈希键的值 Ruby

第7章

来自哈希函数的相同键的不同值和良好的哈希值

使用整数值作为哈希表的键是多么愚蠢?