Массив расщепления Perl, основанный на условии, используя grep - PullRequest
8 голосов
/ 23 декабря 2011

У меня есть некоторый Perl-код, который выглядит примерно так:

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

Это работает нормально, но я хотел бы разбить исходный массив на два на основе одной операции ... IМне кажется, я выполняю в два раза больше операций, чем это необходимо.

Помощь оценена !!Благодарю.

Ответы [ 3 ]

10 голосов
/ 23 декабря 2011

Здесь part из List :: 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;
}

Если вам нужно выполнить много подобных проверок, возможно, вам следует проверить, что вы проверяете.

my %div;
for my $elem (@array){
  for my $div (2,3,5,7,11,13){
    push @{ $out{$div} }, $elem unless $elem % $div;
  }
}
6 голосов
/ 23 декабря 2011

Безусловно, самый простой способ - это итерация массива и передача значений в любой из двух массивов в зависимости от условия, как показано в следующем примере.

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может быть наоборот.

3 голосов
/ 24 декабря 2011

Мне нравится простота функции 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...