使用grep基于条件的Perl分裂数组

时间:2011-12-23 15:46:38

标签: arrays perl grep

我有一些看起来像这样的perl代码:

my @array = map { rand } ( 1..100 );
my @matching = grep { $_ == $condition } @array;
@array = grep { $_ != $condition } @array;

这样做没问题,但我想做的是根据单个操作将原始数组拆分为两个...我认为我执行的操作数量是严格必要的两倍。

帮助赞赏!!谢谢。

3 个答案:

答案 0 :(得分:10)

这是来自partList::MoreUtils派上用场的地方。

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;
}

如果你需要做很多类似的检查,也许你应该循环你的测试对象。<​​/ p>

my %div;
for my $elem (@array){
  for my $div (2,3,5,7,11,13){
    push @{ $out{$div} }, $elem unless $elem % $div;
  }
}

答案 1 :(得分:6)

到目前为止,最简单的方法是迭代数组并根据条件将值推送到两个数组中的任何一个,如下例所示。

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的实现方式不同,实际上可能相反。

答案 2 :(得分:3)

我喜欢List::MoreUtils'part功能的简单性:

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

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