如何在 Perl 中检测散列中的空字段?

How can I detect empty fields in a hash in Perl?

我正在使用 DBI 将 MySQL table 中的完整行提取到哈希中,但无法弄清楚如何检测那些空字段。

下面的代码有点草率,因为我尝试了不同的方法来找到解决我问题的方法。本质上,下面的循环打印出 MySQL 第一行的内容。有些字段有数据,有些没有。但是不管散列中的任何键是否指向数据,这个循环声明它们中的每一个都被定义,但是是空的。我想,我错过了一些如此简单的东西,但找不到它。

my %currec; 
foreach my $row (@{$data_all})
{
    say $row;
    %currec = %{$row};
    foreach my $columns (keys %currec) {
      my $text = $currec{$columns};
      say $text;
      if(undef($text))
      {
        say "$columns is NOT DEFINED";
      }
      elsif (length($text) < 1)
      {
        say "$columns DEFINED, but empty";
      }
    }
    exit;

}

undef() 取消定义变量并且总是 returns 未定义的值...

尝试:

...
if(!defined($text))
...

另见我对 In Perl, how can I concisely check if a $variable is defined and contains a non zero length string? 的回答。

你的问题是你查错了。你想要 defined 而不是 undef。我通常会通过一些调试语句找到这些情况:

print "Before check, text is <$text>\n";
if(undef($text))   # you wanted defined() here
  {
    say "$columns is NOT DEFINED";
  }
print "After check, text is <$text>\n";

但是,其他人可能出于不同的原因有相同的问题,所以这是他们的答案。

在 Perl 中,有两种方法可以使某物为“空”。您的数据库也有多种方式,然后您如何处理数据(例如使用空字符串表示 NULL)是另一种方式。在这些问题中,我通常会遍历整个数据路径,看看值是如何处理的。如果事物应该为 NULL,则不应决定将其设为 NULL。所有这些都是一个更长的答案:

  • table 和列定义
  • 将插入或更新值的程序输入
  • 插入值的查询
  • 读取值的程序

返回 Perl 值。

首先,Perl“值”可以没有值(想一想!)。你说你的价值观是明确的,所以这可能不是你的情况。 undef 是您使用有意义的内容之前的默认“值”。使用 defined:

检查
 if( not defined($n) ) { ... }

其次,您的值可能是空(零宽度)字符串。它是一个没有字符的字符串,与其他字符串一样好。有些东西不喜欢undef,把它转成空串。有时会发生这种情况,因为数据路径上的某些东西将值视为字符串并且 undef 被转换为空字符串。检查 length 可以检查那些:

 if( ! length($n) ) { ... }

并且,从 Perl v5.12 开始,length returns undef 用于 undef 值,之前它返回 0

如果数据路径上的某些东西被 undef 视为数字,则该值将是 0(默认数值,即加法标识)。奇怪的是,有一个数值然后转换为一个字符串会给你一个非零长度的字符串。

但是你也问了哈希。散列值可以是我刚才提到的任何值,但散列中可能不存在键。对于任何不存在的键,Perl returns 使用该键时的 undef 值。在使用该键之前,您可以将其用作保护条件:

if( exists $hash{$key} ) { ... }