如何在不使用 Perl 循环的情况下过滤数组?
Posted
技术标签:
【中文标题】如何在不使用 Perl 循环的情况下过滤数组?【英文标题】:How can I filter an array without using a loop in Perl? 【发布时间】:2011-04-26 23:29:11 【问题描述】:这里我试图只过滤没有子字符串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.
$
我想将数组作为参数传递给子例程。
我知道一种方法是这样的
$ 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
$
我想知道是否有办法不使用循环(使用一些简单的过滤)。
【问题讨论】:
【参考方案1】:那就是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";
【讨论】:
【参考方案2】:使用grep
:
sub remove_worlds grep !/world/, @_
例如:
@arrf = remove_worlds @arr;
使用grep
最适合您的特定问题,但为了完整性,您也可以使用map
:
sub remove_worlds map /world/ ? () : $_, @_
这里有点笨拙,但是map
给了你一个钩子,以防你想在丢弃它们之前处理过滤的元素。
【讨论】:
很高兴在这里有参考链接。!/match/
否定匹配语法至关重要。我一直在考虑 map 和其他解决方案,但对于 perl,它们似乎都太笨重了。【参考方案3】:
使用grep
@no_world_for_tomorrow = grep !/world/ @feathers;
详情请perldoc -f grep
。
【讨论】:
【参考方案4】:您可以将grep
函数用作:
@arrf = grep(!/world/, @arr);
为数组@arr
的每个元素计算表达式!/world/
,并返回表达式计算为真的元素列表。
表达式/world/
搜索单词world
并且确实存在。如果字符串world
不存在,则表达式!/world/
为真。
【讨论】:
以上是关于如何在不使用 Perl 循环的情况下过滤数组?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 Group By / 有函数的情况下过滤 SQL 中的数据
如何在没有 Shiny 的情况下过滤 Rmarkdown 中的预聚合数据?