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

When I use Data Dumper to view my array I see this

$VAR1 = 'stuff'; $VAR2 = ''; $VAR3 = 'stuff'; $VAR4 = ''; $VAR5 = '10'; $VAR6 = ''; $VAR7 = '-'; $VAR8 = '';
This is how I tried to remove it, and it didn't work:
do { $a_counter = 0; foreach my $x(@left_split) { if($x eq '') { splice @left_split, $a_counter-1, 1; $bool = 1; last; } } }

Replies are listed 'Best First'.
Re: Unable to remove items from an array that are empty ' '
by choroba (Cardinal) on Apr 25, 2015 at 21:14 UTC
    Where do you increment $a_counter?

    This is how you can fix it:

    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; my @left_split = ('stuff', '', 'stuff', '', '10', '', '-', ''); my $index = 0; while ($index <= $#left_split) { if ('' eq $left_split[$index]) { splice @left_split, $index, 1; } else { ++$index; } } print Dumper \@left_split;

    But I would simply use grep:

    @left_split = grep '' ne $_, @left_split;
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Unable to remove items from an array that are empty ' '
by toolic (Bishop) on Apr 25, 2015 at 21:18 UTC
    grep length is one way:
    use warnings; use strict; use Data::Dumper; my @ls = ('stuff', '', 'stuff', '', 10, '', '-', ''); @ls = grep {length} @ls; print Dumper(\@ls); __END__ $VAR1 = [ 'stuff', 'stuff', 10, '-' ];
Re: Unable to remove items from an array that are empty ' '
by davido (Cardinal) on Apr 25, 2015 at 22:07 UTC

    One problem is modifying the size of an array while iterating over it with a foreach loop is unhealthy. If we were programming in C++ one would say that the splice invalidates the iterator. We don't have such well defined terminology for what you're doing, in Perl. But the effect is similar.

    Additionally, even if this did work as you intended, you're doing way too much work. To splice out an element within an array, all elements to the right need to shift leftward one. So each and every splice is a linear operation. And the general algorithm of filtering an array using a loop and splice will have quadratic growth. If you're willing to trade memory for speed, a better solution is one that populates a new array (even if internally) with the elements filtered from the original array. This sort of algorithm has a linear order of growth as the array's size grows.

    Not only is this better algorithm an order of magnitude faster, it's also far easier to write, especially since that's what the Perl built-in grep function does just that:

    my @array = ( 'stuff', '', 'stuff', '', '10', '', '-', '' ); @array = grep { $_ ne '' } @array;

    If you want to remove all elements that have either an empty string, or are not defined, you could just do this:

    @array = grep length, @array;

    This works because length returns a false value for empty strings, as well as for containers that are 'undef'.

    my @array = ( 'stuff', '', 'stuff', '', '10', '', '-', '' );

    So on the first iteration


    Dave