perl - 如何将数组转换为散列,并将变量名映射为 Perl 中的键?

标签 perl stringify

我发现自己在 perl 中经常使用这种模式

sub fun {
    my $line = $_[0];
    my ( $this, $that, $the_other_thing ) = split /\t/, $line;
    return { 'this' => $this, 'that' => $that, 'the_other_thing' => $the_other_thing};
}

显然,我可以通过返回将给定变量数组转换为映射的函数的输出来简化此模式,其中键与变量同名,例如

sub fun {
    my $line = $_[0];
    my ( $this, $that, $the_other_thing ) = split /\t/, $line;
    return &to_hash( $this, $that, $the_other_thing );
}

随着元素数量的增加,它会有所帮助。我该怎么做呢?看起来我可以组合 PadWalker 和闭包,但我想要一种仅使用核心语言来完成此操作的方法。

编辑:thb 为这个问题提供了一个聪明的解决方案,但我没有检查它,因为它绕过了很多困难的部分 (tm)。如果您想依赖核心语言的解构语义并插入您对实际变量的反射(reflection),您会怎么做?

EDIT2:这是我暗示使用 PadWalker 和闭包的解决方案:

use PadWalker qw( var_name );

# Given two arrays, we build a hash by treating the first set as keys and
# the second as values
sub to_hash {
    my $keys = $_[0];
    my $vals = $_[1];
    my %hash;
    @hash{@$keys} = @$vals;
    return \%hash;
}

# Given a list of variables, and a callback function, retrieves the
# symbols for the variables in the list.  It calls the function with
# the generated syms, followed by the original variables, and returns
# that output.
# Input is: Function, var1, var2, var3, etc....
sub with_syms {
    my $fun = shift @_;
    my @syms = map substr( var_name(1, \$_), 1 ), @_;
    $fun->(\@syms, \@_);
}

sub fun {
    my $line = $_[0];
    my ( $this, $that, $other) = split /\t/, $line;
    return &with_syms(\&to_hash, $this, $that, $other);
}

最佳答案

你可以使用 PadWalker尝试获取变量的名称,但这确实不是您应该做的事情。它是脆弱的和/或有限的。

相反,您可以使用哈希切片:

sub fun {
   my ($line) = @_;
   my %hash;
   @hash{qw( this that the_other_thing )} = split /\t/, $line;
   return \%hash;
}

如果您愿意,可以将切片隐藏在函数 to_hash 中。

sub to_hash {
   my $var_names = shift;
   return { map { $_ => shift } @$var_names };
}

sub fun_long {
   my ($line) = @_;
   my @fields = split /\t/, $line;
   return to_hash [qw( this that the_other_thing )] @fields;
}

sub fun_short {
   my ($line) = @_;
   return to_hash [qw( this that the_other_thing )], split /\t/, $line;
}

但如果您坚持,这里是 PadWalker 版本:

use Carp      qw( croak );
use PadWalker qw( var_name );

sub to_hash {
   my %hash;
   for (0..$#_) {
      my $var_name = var_name(1, \$_[$_])
         or croak("Can't determine name of \$_[$_]");
      $hash{ substr($var_name, 1) } = $_[$_];
   }
   return \%hash;
}

sub fun {
   my ($line) = @_;
   my ($this, $that, $the_other_thing) = split /\t/, $line;
   return to_hash($this, $that, $the_other_thing);
}

关于perl - 如何将数组转换为散列,并将变量名映射为 Perl 中的键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9913894/

相关文章:

javascript - 在 JSON.stringify() 的输出中隐藏空值

c# - 在反序列化期间将 JSON 日期转换为 .NET DateTime 的正确方法

javascript - JSON 中的 JSON 字符串

javascript - JSON.stringify 没有对整个对象进行字符串化

perl - "Can' t 修改非左值子程序调用"当从方法中添加 Moose 属性时

regex - 在 Perl 替换中使用包含文字转义的字符串变量

perl - 这段perl代码是什么意思?

perl - 如何将所有 CPAN 模块更新到最新版本?

regex - 限制perl中的for循环

javascript - 无法解析数组中的字符串化数组