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

Hi monks

Im a novice.

can i delete an element from array just by mentioning the element value.

For example,

@a=('a','b','c','a','b');

in the above array can i delete the first 'a' present in that array. the resultant array should be

@a=('b','c','a','b');

how can i do this?

Thanks in advance.

Replies are listed 'Best First'.
Re: Array element deletion
by Roger (Parson) on May 04, 2004 at 13:17 UTC
    You could use the splice function:
    splice @a, 0, 1; # | | # | +-- length # +----- offset #

    Type perldoc -f splice on the command-line to get help on the splice function.

    To delete an element based on the value...
    for (0..$#a) { if ($a[$_] eq 'a') { splice @a, $_, 1; last; # exit the for loop because only want to delete # the first match } }

    If you want to remove all occurance of an element, it's actually easier:
    @a = map { /a/ ? () : $_ } @a;

      Why didn't you say that map with grep? I mean, that's what it is *there* for. Map's empty list is normally only important as a refinement on grep.

      splice?!? Why not just shift?
      shift @a;

      Of course, that doesn't work if you have to find and remove an array element. Then, indeed, splice or grep are the way to go.

Re: Array element deletion
by matija (Priest) on May 04, 2004 at 13:29 UTC
    Are you sure you need an array? If you just need a structure where you can refer to elements by their value, you'll be much better off with a hash:<code? %a=(a=>2,b=>1,c=>1,d=>1); # a hash can't have two elements which are the same </code>

    To see if an element exists in a hash, you check $a{'b'} for instance. To delete an element, you simply say delete($a{'b'});

    For an array which might have more than one element the same ( but where order of elements isn't important) you could keep a count of elements in each hash value, and decrement it when you delete the element - then use delete only if the value reaches zero.

    If you must use an array (due to other things you didn't talk about needing an array), then splice is your best bet, as was mentioned above: but you'll have to write a routine that scans through the elements and returns the index of the desired element.

Re: Array element deletion
by pelagic (Priest) on May 04, 2004 at 13:18 UTC
    perldoc -f splice

    pelagic
Re: Array element deletion
by perlinux (Deacon) on May 04, 2004 at 13:22 UTC
    Try this:
    UPDATE:
    @a=('a','b','c','a','b'); @a=reverse(@a); pop(@a); @a=reverse(@a); print @a'
    i.e.:
    shift(@a);
    Hypnotic? :-)
      While you were hypnotized, you completely missed the point of the OP's question. Given a certain value, remove the first occurrence of it in an array.

      --
      [ e d @ h a l l e y . c c ]

        That's a generalization that may or may not be true. The op may want all but the last of a certain character removed, or the first (or all but the last) of every duplicated character.