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.
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;
}
}
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);
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With