Condition-based perl splitting array using grep

I have Perl code that looks something like this:

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

This works fine, but what I would like to do is split the original array into two based on one operation ... I think I perform twice as many operations as necessary.

Help rate! Thank you

+8
arrays grep perl
source share
3 answers

The easiest way is to iterate your array and pass the values ​​to either of the two arrays depending on the condition, as in the example below.

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

If you want to change the original 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?

This module may not exist on the target system, which is always annoying.

Also, on the system I ran tests, I found that List::MoreUtils::part was twice as slow as the first fragment in this post, although with different implementations of part this could be the other way around.

+6
source share

Here the 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 input element to be in the same output array.


If you want to possibly put them in multiple arrays, you should loop them yourself.
The best way to do this 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 you need to do a lot of these tests, you might want to focus on what your testing is against.

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

I like the simplicity of the List::MoreUtils ' part function:

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

The resulting @parts array is an arrayrefs array. @$parts[0] is an array of elements that return false. @$parts[1] returns true.

+3
source share

All Articles