my @array = qw(hi hello howdy); my @hellos = grep_and_remove { $_ eq 'hello' } @array; use Data::Dumper; print Dumper \@array; __END__ $VAR1 = [ 'hi', 'howdy' ]; #### sub grep_and_remove (&\@) { my ($cb, $array_ref) = @_; my @found; my $src = -1; my $dst = -1; while (++$src < @{ $array_ref }) { my $match; for ($array_ref->[$src]) { $match = $cb->(); } # compact non-matches in-place of array ($match ? $found[@found] : $array_ref->[++$dst] ) = $array_ref->[$src]; } # truncate redundant end $#{ $array_ref } = $dst; return @found; }