有没有一种简单的方法来验证散列元素的散列存在和被定义?
我需要验证散列元素的Perl散列,如$Table{$key1}{$key2}
存在并被定义。这是我做的。 (我不知道$key1
存在的话)有没有一种简单的方法来验证散列元素的散列存在和被定义?
if
((defined $Table{$key1}) &&
(exists $Table{$key1}) &&
(defined $Table{$key1}{$key2}) &&
(exists $Table{$key1}{$key2}))
{
#do whatever
}
是否有更简单和更清洁的方式做到这一点?
你不需要检查每个等级的等级:你可以为你关心的价值。 exists
不检查定义,只有当散列中的槽存在(它可能存在一个未定义的值),所以如果你关心定义的值,你需要调用defined
而不是存在。如果没有定义的值,它计算在布尔上下文中为假,所以我们可以键入少一点,减少您的例子:
if ($Table{$key1}{$key2})
{
# do whatever
}
但是,如果该键的值定义,但“假” (数值计算结果为零,或为空字符串),这可能会导致假阴性,所以我们应该明确地检查definedness如果这是一个可能性:
if (defined $Table{$key1}{$key2})
{
# do whatever
}
如果你不想autovivify $Table{$key1}
,你可以检查其存在第一,这给我们带来了“最好”的方式对于一般情况:
if (exists $Table{$key1} and defined $Table{$key1}{$key2})
{
# do whatever
}
如果你要这个做了很多关于各个领域中的哈希,你可能要增加一些面向对象式的存取方法,其愿意为你做这项工作:
sub has_field
{
my ($this, $fieldName) = @_;
return exists $this->{data} && defined $this->{data}{$fieldName});
}
我敢肯定你已经阅读过它,但它不能伤害再次阅读相关文章:
鉴于指定的哈希元素或数组元素,
exists
返回true,如果在散列或数组中指定的元件曾经被初始化的表达,即使相应的值是未定义。如果该元素不存在,则该元素不会自动生效。
...
散列或数组元素可以是真实的,只有当它的定义,如果它存在定义,但反过来不一定成立。
这将始终autovivifiy'$表{$键1}'如果它不存在 – 2010-04-27 17:47:57
@Eric:看到最新的编辑:) – Ether 2010-04-27 17:49:39
我会做出错误的代码通过将各种意见围绕它说:“唐脱颖而出不要这样做!!!!!!!“ – 2010-04-27 18:41:18
以下是短,从autovivifcation将保护:不需要
if (exists $table{$key1} and defined $table{$key1}{$key2}) {...}
在你的代码的其他检查。
检查存在,然后再定义的烦躁。 (A值可以不被限定,但没有现有不能定义存在。)应该与exists
测试中间水平,以防止意外的自动激活。在过去的水平,你只需要调用defined
。当没有太多层可以很容易地直接代码:
if (exists $hash{a} && defined $hash{a}{b}) {...}
如果有许多层,这得到尴尬:
if (exists $hash{a} && exists $hash{a}{b} && exists $hash{a}{b}{c} ...) {...}
在这种情况下,你可以写一个版本的defined
那并不“T autovivify中间值:
sub safe_defined {
my $h = shift;
foreach my $k (@_) {
if (ref $h eq ref {}) {
return unless exists $h->{$k};
$h = $h->{$k};
}
else {
return;
}
}
return defined $h;
}
你使用这种方式:
if (safe_defined(\%hash, qw(a b c))) {
say $hash{a}{b}{c};
}
注:该版本功能是有限的。
- 它只能处理嵌套的哈希值。 Perl中,您可以构造任意的数据 结构,像标引用数组的哈希...
- 它不支持有福引用(即对象)。
一个真正的通用版本就留给读者自己练习。 ;)
你可以检查出Data::Diver。它没有autovivifying潜入数据结构。语法是:
if (defined Dive(\%Table, $key1, $key2)) { ... }
甚至:
if (defined(my $value = Dive(\%Table, $key1, $key2))) {
...do something with $value...
}
太好了!谢谢大家的回复。
由于autovivifying对我来说是一个问题,目前我使用的是 “尴尬” 的方式,即 如果(存在$表{$键1} & &定义$表{$键1} {$键2}){
什么就做什么
}
它为我,但是作为你们说的,我有3-4级深度嵌套散列,代码凌乱位。
我会检查出数据:潜水员。那个看起来更好。
再次感谢,
请编辑您的问题使用代码块代码。 – justkt 2010-04-27 17:36:53