in reply to delete array element from array ref

Perl presents arrays as dynamic but not sparse. As soon as you access element n, all the elements 0 .. n - 1 pop into existence with the value of undef if they didn't exist already. Deleting the contents of elements from the middle of an array doesn't change its length.

However, under the hood things are a little more complicated. Consider:

my @array; $array[4] = 0; print " Set element 4: last at $#array\n"; $array[2] = undef; delete $array[4]; print "Delete element 4: last at $#array\n"; delete $array[2]; print "Delete element 2: last at $#array\n";

Prints:

Set element 4: last at 4 Delete element 4: last at 2 Delete element 2: last at -1

so Perl differentiates between array elements that have been assigned to (even if the assignment was undef - that is, the element exists) and unassigned elements (the element doesn't 'exist'). Perl truncates an array back to the last element that exists when element [-1] is deleted. Otherwise, delete simply makes an array element "unassigned" (it doesn't exist any more).

If you want to remove the elements without leaving holes you could use splice or assign a slice that is the complement of the elements you want to remove:

use strict; use warnings; use strict; use Data::Dump ('dump'); my $listref = ['a','b','c','d','e']; @$listref = @{$listref}[0, 2, 4]; print "@$listref\n";

Perl reduces RSI - it saves typing

Replies are listed 'Best First'.
Re^2: delete array element from array ref
by jlf (Scribe) on Aug 22, 2008 at 06:14 UTC
    Another way to avoid holes would be to filter out the holes with something like

    @{$listref} = grep { defined } @{$listref};

    after performing the deletion. (Of course that assumes that undef isn't a valid value in the list.)

      Better would be:

      @{$listref} = grep {exists} @{$listref};

      Update: this is of course complete bolix as pointed out by tinita++.


      Perl reduces RSI - it saves typing
        @{$listref} = grep {exists} @{$listref};
        maybe you meant:
        @{$listref} = map { exists $listref->[$_] ? $listref->[$_] : () } 0 .. $#{$listref} ;
        ?

        update: typo