Re: Invisible Array Loop Counter?

From: Paul Lalli (ittyspam_at_yahoo.com)
Date: 06/02/04


Date: Tue, 1 Jun 2004 18:47:08 -0400

On Tue, 1 Jun 2004, zzapper wrote:

> In fact none of the three methods actually shortened the array
>
> @t=@r=@q=qw(fred joe freddy sick);
>
> for (@q)
> {
> delete $q[$cnt] if /fred/;
> $cnt++;
> }
> print @q;
>
> for (0..$#r)
> {
> delete $r[$_] if $r[$_] =~ /fred/;
> }
> print @r;
>
> for (@t)
> {
> $_="" if /fred/;
> }
> print @t;
>
> print $#q;
> print $#r;
> print $#t;

Running your code, for all three methods, we see that the sizes of the
arrays are still four. However, printing out the values shows only the
'joe' and 'sick' elements. Why is this? Well, I modified your code to
print out the full contents of the arrays, using Data::Dumper.

use Data::Dumper;
@t=@r=@q=qw(fred joe freddy sick);
for (@q)
{
   delete $q[$cnt] if /fred/;
   $cnt++;
}
for (0..$#r)
{
   delete $r[$_] if $r[$_] =~ /fred/;
}
for (@t)
{
   $_="" if /fred/;
}

print Dumper(\@q)
print Dumper(\@r)
print Dumper(\@t);
__END__

And here's the output:

$VAR1 = [
          undef,
          'joe',
          ${\$VAR1->[0]},
          'sick'
        ];
$VAR1 = [
          undef,
          'joe',
          ${\$VAR1->[0]},
          'sick'
        ];
$VAR1 = [
          '',
          'joe',
          '',
          'sick'
        ];

What we see here is that in the first method, the first element you tried
to delete actually became undef, and the third element became a reference
back to that first element. (Right? Someone back me up here, or tell me
if that's wrong).
In the second method, a similar event happened.
In the third, you successfully modified the array so that the first and
third elements are equal to the empty string.

So in all cases, you modified the actual elements, without removing them
from the array. This is the behavior of the 'delete' function. (See
perldoc -f delete for more info).

Compare this to the method I suggested:
use strict;
use warnings;
use Data::Dumper;

my @q = qw(fred joe freddy sick);
@q = grep { !/fred/ } @q;
print Dumper (\@q);
__END__

$VAR1 = [
          'joe',
          'sick'
        ];

This method actually removes the elements from the array.

Paul Lalli



Relevant Pages

  • Re: Get the results in reverse order
    ... I need to get the first element, that is the newest, and then the rest ... How do i get the rest of the rows in reverse order? ... Store everything in an array. ... Prototype.js was written by people who don't know javascript for people ...
    (comp.lang.php)
  • Re: is there a compiler warning for this piece of code ?
    ... Thanks for your thoughts - I think your speculation as to the history of the ... An element of a char array cannot be NULL; ... > _address_ of the first element. ... >> Incorrect. ...
    (microsoft.public.vc.language)
  • Re: Fast lookup of ranges
    ... I have a peculiar (atleast to me) problem before my hand. ... big table with numeric ranges in each row. ... and the first element is always less than ... Chose an array length N, the larger the faster we can search. ...
    (comp.programming)
  • Re: writing get_script()
    ... to the highest index. ... remove the first element from an array. ... print "$verse $script\n"; ...
    (comp.lang.perl.misc)
  • Re: Please, I am going insane: First element access causing ArrayIndexOutOfBoundsException:0
    ... I have an array created that has ... I feed the results of the query into the array... ... same error when i try to access the first element. ... its own prepared statement and resultset and it fixed the problem. ...
    (comp.lang.java.programmer)