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

Hi monks,

Can anyone tell me if it is possible to remove a value from an array if I only know the value and not the index?
Basically I want to:
if ( grep $term =~ /^(.*)$term(.*)$/, @terms ) { #remove the value that $term matched from the array } # end-if
Cheers,
Reagen

Update
As pointed out by conrad i did indead mean:
$_ =~ /^(.*)$term(.*)$/
Thanks conrad :)

the inclusion of the (.*) in the regex was just to demostrate that it wasnt just going to be a regex of /$term/. I guess i should have use a more complex regex...

Replies are listed 'Best First'.
Re: remove value from array without index
by conrad (Beadle) on Dec 09, 2004 at 13:39 UTC

    How about this?

    @terms = grep ! /^(.*)$term(.*)$/, @terms;

    (not sure why your regexp isn't simply /$term/, and your original if statement seems confused, I presume you meant $_ =~ /^(.*)$term(.*)$/…)

Re: remove value from array without index
by davorg (Chancellor) on Dec 09, 2004 at 13:39 UTC

    You were pretty close with your use of grep.

    #!/usr/bin/perl use strict; use warnings; my @terms = qw(a list of terms); my $term = 'of'; @terms = grep { $_ ne $term } @terms; print "@terms";

    Note that this is one of those cases where the use of regexes makes things more complex that necessary.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: remove value from array without index
by fglock (Vicar) on Dec 09, 2004 at 13:41 UTC

    Use a negated grep()

    use strict; my @x = grep { ! /2/ } qw( 1 2 3 11 12 13 ); print "@x"; 1 3 11 13
Re: remove value from array without index
by calin (Deacon) on Dec 09, 2004 at 17:29 UTC

    Be aware that a whole array assignment (@ary = ...) actually drops the existing elements and then fills the array with new ones. This will lead you into problems if you keep scalar references to array elements. The references will no longer point to the elements in the array.

    In order to remove elements while preserving the integrity of references, you need to splice them out:

    #!/usr/bin/perl my $term = 'foo'; my @ary = qw/one foo another foo too many foos/; # print elements and addresses before print "$_->[0] => $_->[1]\n" for map {[$_ => \$_]} @ary; for (my $i = 0 ; $i < @ary ; $i++) { splice @ary, $i, 1 and @ary - $i and redo if $ary[$i] eq $term; } # print elements and addresses after print "\n"; print "$_->[0] => $_->[1]\n" for map {[$_ => \$_]} @ary;

    With example output:

    one => SCALAR(0x80f57ac) foo => SCALAR(0x80f58a8) another => SCALAR(0x80f56bc) foo => SCALAR(0x80fc944) too => SCALAR(0x80ff6c4) many => SCALAR(0x80ff6d0) foos => SCALAR(0x80ff6dc) one => SCALAR(0x80f57ac) another => SCALAR(0x80f56bc) too => SCALAR(0x80ff6c4) many => SCALAR(0x80ff6d0) foos => SCALAR(0x80ff6dc)