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:

my @x = qw( eenie meenie minie moe ); my @y = cull { /m.*nie/ } @x; print "@y\n"; print "@x\n"; __END__ meenie minie eenie moe
Note that when invoked as shown, it is not necessary to include the sub keyword nor to precede the array with \.

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:

my @x = grep { /m.*nie/ } qw( eenie meenie minie moe ); my @y = cull { /m.*nie/ } qw( eenie meenie minie moe );
Of course, these are OK too:
my @y = cull sub { /m.*nie/ }, @x; my @y = cull( sub { /m.*nie/ }, @x );
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 line
for my $i ( reverse 0 .. $#$array ) {
as suggested. Thanks.

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; }

In reply to cull by tlm

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.