Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl splitting array based on condition using grep

Tags:

arrays

grep

perl

I have some perl code that looks something like this:

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

This works ok, but what I would like to do is split the original array into two based on a single operation...I think I'm carrying out twice as many operations as strictly necessary.

Help appreciated!! Thanks.

like image 637
distracted-biologist Avatar asked Dec 23 '11 15:12

distracted-biologist


2 Answers

This is where part from List::MoreUtils comes in handy.

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

This works great if you want each element of input in exactly one array of the output.


If you want to possibly put them in more than one of the arrays, you have to loop over them yourself.
The best way to do that is with a foreach loop.

my(@div2,@div3);
for my $elem (@array){
  push @div2, $elem unless $elem % 2;
  push @div3, $elem unless $elem % 3;
}

If there are a lot of similar checks you have to do, perhaps you should loop on what your testing against as-well.

my %div;
for my $elem (@array){
  for my $div (2,3,5,7,11,13){
    push @{ $out{$div} }, $elem unless $elem % $div;
  }
}
like image 124
Brad Gilbert Avatar answered Sep 22 '22 19:09

Brad Gilbert


By far the easiest method is to iterate your array and push values to either of the two arrays depending on the condition, as in the below example.

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

If you'd like to modify the source array:

for (my $i =0; $i < @array; ++$i) {
  if ($array[$i] % 2) {
    push @odd, splice (@array, $i--, 1);
  }
}

Why didn't you recommend List::MoreUtils::part?

The module in question might not exists on the target system, which is always an annoying thing.

Also on the system I ran tests on I found that List::MoreUtils::part was twice as slow as first snippet in this post, though with different implementations of part it might be the opposite actually.

like image 25
Filip Roséen - refp Avatar answered Sep 22 '22 19:09

Filip Roséen - refp