in reply to Re^2: Splitting array into two with a regex
in thread Splitting array into two with a regex

To generalize it even further:

sub partition (&$@) { my $condition = shift; my $receivers_ar = shift; push @{ $receivers_ar->[ &$condition ] }, $_ for @_; @$receivers_ar } # Example 1: my( @good, @bad ); partition { /u/ ? 1 : 0 } [ \@good, \@bad ], qw( foo bar quux ); print "good=@good\n"; print "bad=@bad\n"; # Example 2: my @r = partition { $_ % 3 } [ [], [], [], ], 0 .. 12; for my $i ( 0 .. $#r ) { print "$i = @{$r[$i]}\n"; }
We're building the house of the future together.

Replies are listed 'Best First'.
Re^4: Splitting array into two with a regex
by dragonchild (Archbishop) on Nov 08, 2005 at 17:58 UTC
    Since we're using prototypes, another way might look like:
    sub partition (&\@\@\@) { my ($cond, $start, $true, $false) = @_; for (@$start) { push @{ $cond->() ? $true : $false }, $_; } return; } my @arr = 1 .. 9; my (@greater, @less); partition { $_ > 5 } @arr => @greater, @less; print "@greater\n@less\n";

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re^4: Splitting array into two with a regex
by Roy Johnson (Monsignor) on Nov 08, 2005 at 16:33 UTC
    Nice. Note that Example 2 can be called as such:
    my @r = partition { $_ % 3 } [], 0 .. 12;
    and autovivification will create the sub-refs, though only for those elements that actually get assigned to. It's probably best to go ahead and specify the arrayrefs, but it could be a little cumbersome. It can be made simpler by a little tweak: the 2nd argument can be an arrayref or a number; if a number, partition creates that many sub-array(ref)s.
    sub partition (&$@) { my $condition = shift; my $receivers_ar = shift; ref $receivers_ar or $receivers_ar = [ map [], 1..$receivers_ar ]; push @{ $receivers_ar->[ &$condition ] }, $_ for @_; @$receivers_ar } my @r = partition { $_ % 3 } 3, 0 .. 12;
    Also note that the map cannot be replaced with ([]) x $receivers_ar because that will make three copies of the same ref.

    Caution: Contents may have been coded under pressure.