use strict; use warnings; use List::MoreUtils qw[firstidx]; sub cull (&\@) { my ($code, $array) = (shift, shift); my @matches; my $count; # let List::MoreUtils (fast!) find the items # splice() returns the items removed.... while ( (my $idx = firstidx { $code->() } @$array) > -1 ) { my $item = splice(@$array,$idx,1); wantarray ? push(@matches, $item) : $count++; } wantarray ? @matches : $count; } my @test = qw[how I wish I could remember pi easily]; my @new = cull { $_ eq 'I' } @test; print join(':',@new), "\n"; print join(':',@test), "\n";