Subject: | wish (and patch): remove, remove_if_not |
Hi,
Thanks for List::MoreUtils. It rocks! :)
I often find myself writing the following code:
my @opts;
@ARGV = map { /^-/ ? do { push @opts, $_; () } : $_ } @ARGV;
This could way more easily be expressed as:
my @opts = remove { /^-/ } @ARGV;
And so I implemented this. :)
Attached is a script with pure-Perl implementations of remove (and
remove_if_not), and some basic tests for them.
Thanks!
Shawn M Moore
P.S. Your mega import in the synopsis misses 'part'.
Subject: | remove.pl |
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More tests => 13;
# pure perl implementations
sub remove(&\@;\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@)
{
my $code = shift;
my @out;
# for each array..
for my $in (@_)
{
# go through each element..
for (my $i = 0; $i < @$in; )
{
# does the check pass?
local $_ = $in->[$i];
if ($code->($_))
{
# if so, add it to the output and continue
push @out, splice @$in, $i, 1;
}
else
{
# otherwise, just continue
++$i;
}
}
}
return @out;
}
sub remove_if_not(&\@;\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@)
{
my $code = shift;
my @out;
# for each array..
for my $in (@_)
{
# go through each element..
for (my $i = 0; $i < @$in; )
{
# does the check pass?
local $_ = $in->[$i];
if (!$code->($_))
{
# if so, add it to the output and continue
push @out, splice @$in, $i, 1;
}
else
{
# otherwise, just continue
++$i;
}
}
}
return @out;
}
# aliases
BEGIN {
no warnings 'once';
*remove_if = \&remove;
*remove_unless = \&remove_if_not;
}
# some tests
my @a = qw(1 2 3 4 5);
my @b = remove { $_ < 3 } @a;
is_deeply(\@a, [qw(3 4 5)]);
is_deeply(\@b, [qw(1 2)]);
my @argv = qw(--foo bar -b az quux);
my @args = remove { /^-/ } @argv;
is_deeply(\@argv, [qw(bar az quux)]);
is_deeply(\@args, [qw(--foo -b)]);
my @alpha = qw(a eh alpha altar);
my @beta = qw(b bee beta);
my @tau = remove { /t/ } @alpha, @beta;
is_deeply(\@alpha, [qw(a eh alpha)]);
is_deeply(\@beta, [qw(b bee)]);
is_deeply(\@tau, [qw(altar beta)]);
my @eee = remove { /e/ } @alpha, @beta, @tau;
is_deeply(\@alpha, [qw(a alpha)]);
is_deeply(\@beta, [qw(b)]);
is_deeply(\@tau, [qw(altar)]);
is_deeply(\@eee, [qw(eh bee beta)]);
my @catch = remove_unless { /e/ } @alpha, @beta, @tau;
is_deeply(\@catch, [qw(a alpha b altar)]);
push @tau, 'foo', remove_if { 1 } @catch;
is_deeply(\@tau, [qw(foo a alpha b altar)]);