如何在不使用Perl循环的情况下过滤数组?

Laz*_*zer 28 arrays perl

在这里,我试图仅过滤没有子字符串的元素,world并将结果存储回同一个数组.在Perl中执行此操作的正确方法是什么?

$ cat test.pl
use strict;
use warnings;

my @arr = ('hello 1', 'hello 2', 'hello 3', 'world1', 'hello 4', 'world2');

print "@arr\n";
@arr =~ v/world/;
print "@arr\n";

$ perl test.pl
Applying pattern match (m//) to @array will act on scalar(@array) at
test.pl line 7.
Applying pattern match (m//) to @array will act on scalar(@array) at
test.pl line 7.
syntax error at test.pl line 7, near "/;"
Execution of test.pl aborted due to compilation errors.
$
Run Code Online (Sandbox Code Playgroud)

我想将数组作为参数传递给子例程.

我知道一种方法是这样的

$ cat test.pl 
use strict;
use warnings;

my @arr = ('hello 1', 'hello 2', 'hello 3', 'world1', 'hello 4', 'world2');
my @arrf;

print "@arr\n";

foreach(@arr) {
    unless ($_ =~ /world/i) {
       push (@arrf, $_); 
    }
}
print "@arrf\n";

$ perl test.pl
hello 1 hello 2 hello 3 world1 hello 4 world2
hello 1 hello 2 hello 3 hello 4
$
Run Code Online (Sandbox Code Playgroud)

我想知道是否有办法在没有循环的情况下进行(使用一些简单的过滤).

Rue*_*uel 36

那将是grep():

#!/usr/bin/perl

use strict;
use warnings;

my @arr = ('hello 1', 'hello 2', 'hello 3', 'world1', 'hello 4', 'world2');
my @narr = ( );

print "@arr\n";
@narr = grep(!/world/, @arr);
print "@narr\n";
Run Code Online (Sandbox Code Playgroud)


Gre*_*con 11

用途grep:

sub remove_worlds { grep !/world/, @_ }
Run Code Online (Sandbox Code Playgroud)

例如:

@arrf = remove_worlds @arr;
Run Code Online (Sandbox Code Playgroud)

使用grep是最适合您的特定问题,但为了完整性,您还可以使用map:

sub remove_worlds { map /world/ ? () : $_, @_ }
Run Code Online (Sandbox Code Playgroud)

这里有点笨拙,但是map如果您想要在丢弃它们之前处理过滤后的元素,请为您提供一个钩子.


And*_*ter 10

使用 grep

@no_world_for_tomorrow = grep { !/world/ } @feathers;
Run Code Online (Sandbox Code Playgroud)

详情请问perldoc -f grep.


cod*_*ict 5

您可以使用以下grep功能:

@arrf =  grep(!/world/, @arr);
Run Code Online (Sandbox Code Playgroud)

表达!/world/为阵列的每个元件进行评价@arr,并且其表达评估为真时返回的元素的列表.

表达式/world/搜索单词world并且它是真实存在的.!/world/如果字符串world不存在,则表达式为true .