I imagine there's a few million versions out there of the cull function I'm about to describe, but I couldn't find one in the obvious places (e.g. List::Util, List::MoreUtils, etc.), so here it goes.
The cull function faintly resembles grep. It takes as arguments two references, the first one to a sub, and the second one to an array. It returns all the elements of the array for which the sub evaluates to true, but, contrary to grep it has the side effect of removing these elements from the original array.
Example:
Note that when invoked as shown, it is not necessary to include the sub keyword nor to precede the array with \.my @x = qw( eenie meenie minie moe ); my @y = cull { /m.*nie/ } @x; print "@y\n"; print "@x\n"; __END__ meenie minie eenie moe
As with grep and map, the sub passed as the argument to cull does not get its argument from $_[0], but rather it reads it from $_.
One important difference between cull and grep is that cull takes exactly two arguments: the first one must be a subref (or a code block, but not a boolean expression), and the second one must be an array. Hence, for example, the second statement below would result in an error:
Of course, these are OK too:my @x = grep { /m.*nie/ } qw( eenie meenie minie moe ); my @y = cull { /m.*nie/ } qw( eenie meenie minie moe );
As always, I look forward to reading your comments and suggestions. Update: the point in the comments about the unnecessary expansion of the array indices is a good one, so I changed the original linemy @y = cull sub { /m.*nie/ }, @x; my @y = cull( sub { /m.*nie/ }, @x );
as suggested. Thanks.for my $i ( reverse 0 .. $#$array ) {
sub cull (&\@) { my ( $test, $array ) = @_; my @culled; for ( my $i = $#$array; $i > -1; --$i ) { local $_ = $array->[ $i ]; unshift @culled, splice @$array, $i, 1 if $test->(); } return @culled; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: cull
by hossman (Prior) on Mar 31, 2007 at 23:35 UTC | |
by betterworld (Curate) on Apr 01, 2007 at 03:23 UTC | |
|
Re: cull
by parv (Parson) on Apr 01, 2007 at 21:48 UTC | |
by radiantmatrix (Parson) on Apr 10, 2007 at 16:52 UTC | |
|
Re: cull
by jdporter (Paladin) on Apr 01, 2007 at 16:15 UTC | |
by parv (Parson) on Apr 01, 2007 at 20:45 UTC | |
by jdporter (Paladin) on Apr 02, 2007 at 02:20 UTC |