在perl中的散列内执行数组内的函数

时间:2015-08-21 16:25:07

标签: perl hash

我有像这样的Perl数据结构

%myhash = (
  k1 => v1, 
  kArray => [
    {
      name => "anonymous hash",
      ...
    },
    \&funcThatReturnsHash,
    {
      name => "another anonymous hash",
      ...
    }
  ]
);

在其他地方,我遍历kArray中包含一堆哈希值的列表。我想通过函数处理实际的哈希值或哈希返回的

foreach my $elem( @{myhash{kArray}} ) {

  if (ref($elem) == "CODE") {
     %thisHash = &$elem;
  }
  else {
     %thisHash = %$elem;
  }
  ...
}

但是ref ($elem)始终是标量或未定义的。我在func中尝试&func\&func\%{&func}%myhash无效。

如何在主体中的函数中提取哈希值?

2 个答案:

答案 0 :(得分:2)

除了您提供的无效Perl代码示例之外,主要问题似乎是您使用==来比较字符串而不是eq,并且您正在分配哈希引用到哈希变量%thishash。我向您保证,ref $elem永远不会返回SCALAR您显示的数据

如果您遵循代码顶部的use strictuse warnings的常见建议,那将极大地帮助您

这对你有用

for my $elem ( @{ $myhash{kArray} } ) {

    my $this_hash;

    if ( ref $elem eq 'CODE' ) {
         $this_hash = $elem->();
    }
    else {
         $this_hash = $elem;
    }

    # Do stuff with $this_hash
}

或者您可以像这样使用map

use strict;
use warnings;
use 5.010;

use Data::Dump;

my %myhash = (
    k1     => v1,
    kArray => [
        {
            name => "anonymous hash",
        },
        \&funcThatReturnsHash,
        {
            name => "another anonymous hash",
        }
    ]
);

for my $hash ( map { ref eq 'CODE' ? $_->() : $_ } @{ $myhash{kArray} } ) {
  say $hash->{name};
}


sub funcThatReturnsHash {
    {  name => 'a third anonymous hash' };
}

输出

anonymous hash
a third anonymous hash
another anonymous hash

答案 1 :(得分:1)

如果您启用严格和警告,您将看到:

foreach my $elem(@{mynahs{kArray}}) {

不是有效的。在$之前,您至少需要mynahs

但是考虑到这样的事情 - 你的方法有效 - 这里有一个例子,使用map来运行'代码参考:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

sub gimme_hash {
    return { 'fish' => 'paste' };
}

my $stuff =
    [ { 'anon1' => 'value' }, 
      \&gimme_hash, 
      { 'anon2' => 'anothervalue' }, ];

my $newstuff = [ map { ref $_ eq "CODE" ? $_->() : $_ } @$stuff ];
print Dumper $newstuff;

将该哈希变为:

$VAR1 = [
          {
            'anon1' => 'value'
          },
          {
            'fish' => 'paste'
          },
          {
            'anon2' => 'anothervalue'
          }
        ];

但你的方法确实有效:

foreach my $element ( @$stuff ) {
   my %myhash;
   if ( ref $element eq "CODE" ) {
      %myhash = %{$element -> ()}; 
   }
   else {
      %myhash = %$element;
   }
   print Dumper \%myhash; 
}

给出:

$VAR1 = {
          'anon1' => 'value'
        };
$VAR1 = {
          'fish' => 'paste'
        };
$VAR1 = {
          'anon2' => 'anothervalue'
        };