Perl:使用 grep 进行过滤,包括过滤值的警告



我想使用 grep 过滤数组,但我想为所有过滤的值包含警告,而不是静默地过滤掉它们。 我试过这个:

my @l = (1,2,3,4,5);
@l = grep {
  if ($_%2 == 0) {
    warn "$_ is an even number!!!";
    return 0;
  }
  return 1;
} @l;

但这行不通。我没有收到任何警告,并且列表未被过滤。 我该怎么做?

确实会收到警告(不过您需要use warnings; use strict;(:

Can't return outside a subroutine

这是因为grep接受表达式或块 - 严格来说它不是 sub。

这将起作用:

#!/usr/bin/env perl
use strict;
use warnings;
my @numbers = ( 1, 2, 3, 4, 5 );
my @odd_numbers = grep {
    if ( $_ % 2 == 0 ) {
        warn "even number $_";
        0;
    }
    else {
        1;
    }
} @numbers;
print @odd_numbers;

另外:不要使用单个字母的变量名称。这是糟糕的风格。

该代码与

Can't return outside a subroutine at a.pl line 10.

回调不是子例程。您不能使用 return .

my @l = (1,2,3,4,5);
@l = grep {
  if ($_ % 2) {
    1
  } else {
    warn "even number!!!";
    0
  }
} @l;

多次打印even number!!!并不是那么有用。

my @nums = 1..5;
my @odds = grep { $_ % 2 } @nums;
warn("One or more even numbers!n") if @odds != @nums;

KISS

不要试图变得聪明,grep 确实是从现有列表中创建新列表的正确方法,使用正匹配。是的,你可以在里面做各种花哨的事情。

但是普通的foreach有什么问题呢?只需循环列表,执行任何智能选择,然后将积极因素推到另一个列表中。而且你有一个完整的代码块来处理你不需要的代码块,并出于不同类型的原因发出超级有趣的警告......

foreach my $item ( @numbers ) {
    if ( $item %2 ) {
        warn "fiz";
        next
    }
    unless ( $item % 3 ) {
        warn "buzz";
        next
    }
    push @good, $item
}

几天后每个人都可以知道这里发生了什么

最新更新