如何为perl中的每个未定义哈希定义或设置多个哈希值为零

时间:2017-03-24 21:20:35

标签: perl hash

在下面的代码中,有多个职业,其值为零但未在哈希中定义。示例:%data中未定义管道工,但我需要将$data{'Plumber'}设置为零。可能有多个职业没有任何价值观。我用if-else做了这个,但是有更好的方法吗?

#!/usr/bin/perl
use Data::Dumper;
%data = ('Teacher' => 45, 'Doctor' => 40,'Driver' => '10');
if (exists($data{'Plumber'})) {
   print "Number of doctor is $data{'Plumber'}\n";
}
else {
    $data{'Plumber'} = 0;
    print "Number of doctor is $data{'Plumber'}\n";
}
print Dumper \%data;

有没有办法将%data的所有未定义值设置为零?

条件是 - 首先检查散列中的哪些值是未定义的,并将这些值设置为0,而不是全部。

请参阅下面我的实际代码:[3月30日编辑的问题' 17]

 my %map = (
 blk     => 'Block',
 hrd     => 'Hard',
 sft     => 'Soft',
 success => 'Success',
 unk     => 'Unknown',
 );
 my %report;
 for ( `$stats` ) {
 my ($val, $type) = split;
 $report{$map{$type}} = $val;
 }
 \%report;
 $_ //= 0 for values %report;
 print Dumper \%report;

我无法为哈希%报告中的所有未分配值设置0, 根据下面的评论,我使用$_ //= 0 for values %report;来实现这一点,但是当我映射两个哈希时,我感到困惑,因为我是Perl的初学者 仅供参考.. $stats是一个查询,我用它来从日志和示例输出下面获取一些值。

 10 blk
 20 sft
 50 success

任何想法如何处理这一点都将受到高度赞赏

3 个答案:

答案 0 :(得分:2)

您可以使用默认值:

print "Plumber number: ", ($data{'Plumber'} || 0), "\n";

这将使用0而不是任何Perl的非真值,例如""0undef。如果您有这样的值而不想使用0,请使用//运算符而不是'||

答案 1 :(得分:2)

你可能已经习惯了像Ruby Hash.new(0)这样的东西。 Perl有几个库来实现它,Hash::DefaultValue来自一个好作者。麻烦的是它们依赖于捆绑,Perl让对象像数据类型一样的奇怪方式,这种方式很慢且有警告。

相反,有几种技术。最简单的方法是自己应用默认值,如@Robert's answer中所示,但使用已定义的或//运算符而不是逻辑或||运算符。

my $value = $data{'Plumber'} // 0;

区别很微妙,但它可以保护您免受像""这样的错误值被转换为0.相反,仅当$data{'Plumber'}包含未定义的值时才会使用0默认值不存在。

其次,如果修复了一组键,则可以将所有值显式设置为0.再次,使用//=的已定义或||=版本。

for my $key (@keys) {
    $data{$key} //= 0;
}

有一些封装此默认值的选项。最简单的是将你的哈希包装在一个小类中,为你做这个。

package MyStuff;

sub new {
    my $class = shift;
    my $self = shift;

    return bless $self, $class;
}

sub get {
    my $self = shift;
    my $key = shift;

    return $self->{$key} // 0;
}

则...

my $stuff = MyStuff->new(\%data);
my $val = $stuff->get("Plumber");

方法调用会产生额外的开销,用户必须适应对象界面,但它比搭售更快。

答案 2 :(得分:1)

您的用例允许使用North America预设哈希的所有值。在0

之后添加此内容
my %report;

为什么会这样:

@report{values %map} = (0) x keys %map; 设置哈希值的多个值。 @report{...}的值用作%map的键。 %report生成一个零列表。由于(0) x ...运算符在其右侧需要标量,因此x在标量上下文中执行并生成数字5.因此,keys %map将填充其默认值,之后仅填充存在的值在你的%report被覆盖。