在此代码中,我想访问散列{IS-VAR}
数组的每个元素的键@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'];
答案 0 :(得分:10)
您的代码存在的问题是您在grep
语句中使用if
。这会将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
}
}
答案 1 :(得分:0)
你可以尝试更简单的循环:
for my $cleared (@Cleared) {
if ($cleared->{NAME} eq $entity_name && $cleared->{IS_VAR} eq 'TRUE') {
$var_flag = 1
}
}