在分配之前测试哈希条目是否存在的更好方法

时间:2012-11-17 11:52:05

标签: perl parsing perl-data-structures

我正在寻找一种更好的方法来首先“测试”如果在使用之前存在哈希键。我目前正在编写一个事件日志解析器,它将十六进制数字解码为字符串。由于我无法确定我的解码表是否包含十六进制数字,因此我首先需要在将值分配给新变量之前检查密钥是否存在于哈希中。所以我做的很多是:

if ($MEL[$i]{type} eq '5024') {
  $MEL[$i]{decoded_inline} = $decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"}
    if exists ($decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"})
}

我不喜欢的是表达式$decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"}在我的代码中是两次。上面的线路有更好或更短的版本吗?

3 个答案:

答案 0 :(得分:4)

我怀疑这有点“好”,但我认为它实现的目标是不再提及表达两次。我不确定这种痛苦是值得的,请注意:

my $foo = $decode_hash{checkpoint}; 
my $bar = $MEL[$i]{raw}[128]; 
if ($MEL[$i]{type} eq '5024') { 
  $MEL[$i]{decoded_inline} = $foo->{$bar} 
    if exists ( $foo->{$bar} ); 
} 

答案 1 :(得分:2)

是的,有一种更简单的方法。你知道你只能在数组或哈希中存储引用,对吧?嗯,这有一个很好的副作用。您可以引用深度哈希或数组槽,然后将它们视为标量引用。不幸的副作用是它会对插槽进行自动生成,但是如果你总是要分配给那个插槽,并且只想先做一些检查,那么不要一次又一次地输入内容 - 这不是一个糟糕的方法 - 以及反复索引结构。

my $ref = \$decode_hash{checkpoint}{"$MEL[$i]{raw}[128]"};
unless ( defined( $$ref )) { 
    ...
    $$ref = {};
    ...
}

答案 2 :(得分:1)

只要现有的哈希元素不能有未定义的值,我就会写这个

if ($MEL[$i]{type} eq '5024') {
  my $value = $decode_hash{checkpoint}{$MEL[$i]{raw}[128]};
  $MEL[$i]{decoded_inline} = $value if defined $value;
}

(请注意,您不应该在哈希键周围使用双引号。)