Reputation: 21493
I know you can use grep
to filter an array based on a boolean condition. However, I want to get 2 arrays back: 1 for elements that match the condition and 1 for elements that fail. For example, instead of this, which requires iterating over the list twice:
my @arr = (1,2,3,4,5);
my @evens = grep { $_%2==0 } @arr;
my @odds = grep { $_%2!=0 } @arr;
I'd like something like this:
my @arr = (1,2,3,4,5);
my ($evens, $odds) = magic { $_%2==0 } @arr;
Where magic
returns 2 arrayrefs or something. Does such an operator exist, or do I need to write it myself?
Upvotes: 4
Views: 207
Reputation: 126752
It's probably most succinct to simply push
each value to the correct array in a for
loop
use strict;
use warnings 'all';
my @arr = 1 .. 5;
my ( $odds, $evens );
push @{ $_ % 2 ? $odds : $evens }, $_ for @arr;
print "@$_\n" for $odds, $evens;
1 3 5
2 4
Upvotes: 7
Reputation: 118665
List::UtilsBy::extract_by
is like grep
but it modifies the input list:
use List::UtilsBy 'extract_by';
my @arr = (1,2,3,4,5);
my @evens = @arr;
my @odds = extract_by { $_ % 2 } @evens;
print "@evens\n@odds\n";
Output:
2 4
1 3 5
There is also List::UtilsBy::partition_by
:
my %parts = partition_by { $_ % 2 } @arr;
@evens = @{$parts{0}}; # (2,4)
@odds = @{$parts{1}}; # (1,3,5)
Upvotes: 6