petdance has asked for the wisdom of the Perl Monks concerning the following question:

I threw together the following in a big hurry for my MARC::Record module, but I'm sure it's not the best way to do it.

Should I use grep? splice? I'd also like to return a 1/0 to indicate the number of fields deleted.

sub delete_field($) { my $self = shift; my $deleter = shift; my @scratch; for ( @{$self->{_fields}} ) { push( @scratch, $_ ) unless ( $deleter == $_ ); } @{$self->{_fields}} = @scratch; }

xoxo,
Andy
--
<megaphone> Throw down the gun and tiara and come out of the float! </megaphone>

Replies are listed 'Best First'.
Re: What's the best metaphor for deleting something from a list?
by John M. Dlugosz (Monsignor) on Aug 10, 2001 at 02:28 UTC
    If you're looking at each one and deciding to keep or toss, I think grep is the clearest for those who follow, since that's exactly what that function is for.
    my @scratch= grep {$_ != $deleter } @{$self->{_fields}}; my $retval= @{$self->{_fields}} - @scratch; @{$self->{_fields}} = @scratch;
(dkubb) Re: (2) What's the best metaphor for deleting something from a list?
by dkubb (Deacon) on Aug 10, 2001 at 06:24 UTC

    There is no need to increment a counter to keep track of how many elements are deleted from the array. You can simply get the size before the deletion, and substract the size afterwards to get the difference.

    Here's how I would do it:

    sub delete_field { my $self = shift; my $delete_field = shift; my $before_deletion = @{$self->{_fields}}; @{$self->{_fields}} = grep { $delete_field ne $_ } @{$self->{_fields}}; return $before_deletion - @{$self->{_fields}}; }

    You may also want to check out Removing certain elements from an array, which has some neat idioms somewhat related.

Re: Counting Deletions From List
by tadman (Prior) on Aug 10, 2001 at 05:01 UTC
    In line with what JMD said:
    sub delete_field { my $self = shift; my ($deleter) = @_; my $scrubbed = 0; @{$self->{_fields}} = grep { !(($deleter eq $_) && ++$scrubbed) } @{$self->{_fields}}; return $scrubbed; }
    Which is really just evaluating a match/mismatch case, but with some intermediate code to increment $scrubbed.