使用grep基于条件拆分Perl数组

8
我有一些Perl代码,大致如下:
my @array = map { rand } ( 1..100 );
my @matching = grep { $_ == $condition } @array;
@array = grep { $_ != $condition } @array;

这个代码可以正常工作,但是我想根据单个操作将原始数组拆分成两个数组...我认为我执行的操作数量是必要操作的两倍。

需要帮助!谢谢。

3个回答

10

这就是 List::MoreUtils 中的 part 很实用的地方。

use List::MoreUtils qw'part';
my($even,$odd) = part { $_ % 2 } @array;

如果你想让输入的每个元素只放入输出的一个数组中,那么这个方法非常好用。


如果你希望可能将它们放入多个数组中,则需要自己循环遍历。
最好的方法是使用foreach循环。

my(@div2,@div3);
for my $elem (@array){
  push @div2, $elem unless $elem % 2;
  push @div3, $elem unless $elem % 3;
}
如果您需要执行很多类似的检查,或许您应该循环处理您正在进行测试的内容。
my %div;
for my $elem (@array){
  for my $div (2,3,5,7,11,13){
    push @{ $out{$div} }, $elem unless $elem % $div;
  }
}

我喜欢PP实现中part所使用的索引技巧。 - Zaid

7

目前最简单的方法是遍历数组并根据条件将值推送到两个数组中的一个,如下面的示例所示。

for (@array) {
  if ($_ % 2) {push @odd,  $_}
  else        {push @even, $_}
}

如果您想修改源数组:
for (my $i =0; $i < @array; ++$i) {
  if ($array[$i] % 2) {
    push @odd, splice (@array, $i--, 1);
  }
}

为什么你没有推荐使用List::MoreUtils::part?

可能目标系统上不存在这个模块,这总是一件令人烦恼的事情。

我在测试的系统上发现,List::MoreUtils::part的速度是本帖中第一个片段的两倍,尽管对于不同实现的part来说可能会相反。


1
List::MoreUtils 不存在:是的,即使是你也可以使用CPAN -- 基准测试听起来像是过早优化。代码应该像规范一样易读,直到你知道需要更快的东西,即使在那时,也可以进行不同的优化(例如,XS?) - Tanktalus
我的测试表明,当使用Perl 5.14.2时,part部分在XS方面显著更快(快169%-超过两倍),但在PP方面稍微慢一些(慢52%-略低于一半) - 这是相当合理的速率。@array越大,part的性能就越好。 - Tanktalus
@Tanktalus 是的,使用PP时,自定义函数更快,但与XS相比,它没有任何机会。关于cpan,当然可以通过cpan安装它,但因为一个函数安装整个模块有些过度杀伤力,至少我是这么认为的。 - Filip Roséen - refp
依赖于List::MoreUtils模块的程序包括Ubic、Perl-Critic、Moose、Padre和PPI。如果您真的使用Perl来完成工作,那么您可能已经安装了其中之一,因此List::MoreUtils也已经安装好了。 - Brad Gilbert
@BradGilbert 如果你真的使用Perl来快速完成工作,而不总是在自己的机器上执行它,那么很有可能它并不存在。 - Filip Roséen - refp

3

我喜欢 List::MoreUtilspart 函数之简洁:

sub part (&@) {
    my ($code, @list) = @_;
    my @parts;
    push @{ $parts[ $code->($_) ] }, $_  foreach @list;
    return @parts;
}

产生的@parts数组是一个由数组引用组成的数组。@$parts [0]是返回 false 的元素数组。@$parts [1]返回 true。


有一件事我认为可以添加。如果代码引用的返回值可以是一个数组,那么你就可以将每个元素放入多个输出数组中。 - Brad Gilbert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接