3

在这段代码中,我想访问{IS-VAR}hashes 数组的每个元素的key 的值@Cleared。当它进入循环内部时$_被设置为 的值$_->{'NAME'}

if (grep {$_->{'NAME'} eq $entity_name} @Cleared)
{
  **$is_var = $_->{'IS-VAR'};**
  $var_flag = 1 if ($is_var =~ /^TRUE$/i);
}

有没有办法访问$_->{'IS-VAR'}循环内部的值,在这种情况下$_是元素@Cleared

的结构@Cleared如下:

@Cleared = [NAME => 'xxx',
            TYPE => 'yyy',
            IS-VAR => 'TRUE'];
4

2 回答 2

10

您的代码的问题是您grepif语句中使用。这会将结果grep转换为标量(即找到的元素数grep)。因此,您实际上并不知道哪些元素匹配。

如果将其转换为 for 循环,您将能够访问每个匹配的元素;您的其余代码将逐字运行:

foreach (grep {$_->{'NAME'} eq $entity_name} @Cleared)
{
    $is_var = $_->{'IS-VAR'};
    $var_flag = 1 if ($is_var =~ /^TRUE$/i);
}

但是,如果您只是想查找单行是否匹配,则可以将其全部压缩到一个 grep 中:

my $is_var = grep {
    $_->{'NAME'} eq $entity_name && $_->{'IS-VAR'} =~ /^TRUE$/i
} @Cleared;

现在$is_var包含匹配的元素数量的计数。 if ($is_var) {...}如果至少有一个匹配,则为真。

grep但是,如果您只需要知道是否至少存在一个匹配项,这并不是最有效的方法。理想情况下,您应该在找到一个匹配项后立即停止:

my $is_var;
foreach (@Cleared)
{
    if ($_->{'NAME'} eq $entity_name && $_->{'IS-VAR'} =~ /^TRUE$/i)
    {
        $is_var = 1;
        last;          #break out of the loop
    }
}
于 2013-04-25T07:51:28.083 回答
0

您可以尝试更简单的 for 循环:

for my $cleared (@Cleared) {
  if ($cleared->{NAME} eq $entity_name && $cleared->{IS_VAR} eq 'TRUE') {
    $var_flag = 1
   }
}
于 2013-04-25T07:45:01.547 回答