delete from array by reference

M

Michael Goerz

Hi,

how can I delete from an array by reference (i.e. I already have a
pointer to the array element) instead of by index. Consider the
following code:


#!/usr/bin/perl -w
use strict;
use Data::Dumper;

my $testarray = [
["bla", "bla"],
["xyz", "xyz"],
"blabla",
123 ];

print("before:\n", Dumper($testarray), "\n");

my $pointer_to_element = $testarray->[1];

undef($pointer_to_element); # no effect ...
undef(@{$pointer_to_element}); # has *some* effect,
# but only works since I know
# the element is an array
print("after undef by reference:\n", Dumper($testarray), "\n");

undef(@{$testarray}[1]); # ... but I want the same as this
print("after undef by index:\n", Dumper($testarray), "\n");




Even better would be to actually delete, not just to undef the element.

Thanks,
Michael Goerz
 
A

A. Sinan Unur

how can I delete from an array by reference (i.e. I already have a
pointer to the array element)

There is your first mistake. There are no pointers in Perl. Attempting
to draw analogies is futile. Search Google Groups for recent discussions
on this topic in this newsgroup.
instead of by index. Consider the following code:


#!/usr/bin/perl -w
use strict;
use Data::Dumper;

my $testarray = [
["bla", "bla"],
["xyz", "xyz"],
"blabla",
123 ];

print("before:\n", Dumper($testarray), "\n");

my $pointer_to_element = $testarray->[1];

$testarray->[1] is not a pointer to anything. It is a reference to the
anonymous array containing "xyz", "xyz".
undef($pointer_to_element); # no effect ...
undef(@{$pointer_to_element}); # has *some* effect,
# but only works since I know
# the element is an array
print("after undef by reference:\n", Dumper($testarray), "\n");

undef(@{$testarray}[1]); # ... but I want the same as this
print("after undef by index:\n", Dumper($testarray), "\n");

Honestly, I think you have not chosen the right data structure for the
real problem you are trying to solve.

You can use grep to filter out the elements you don't want.

#!/usr/bin/perl

use strict;
use warnings;

my $x = [
[ qw(abc abc) ],
[ qw(xyz xyz) ],
[ qw(edf edf) ],
];

my $e = $x->[1];

$x = [ grep { $_ != $e } @$x ];

use Data::Dumper;
print Dumper $x;

__END__

But repeatedly doing this is bound to be inefficient.

Sinan
--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
 
D

Dr.Ruud

Michael Goerz schreef:
how can I delete from an array by reference (i.e. I already have a
pointer to the array element) instead of by index.

Maybe this helps:

#!/usr/bin/perl
use strict;
use warnings;

my @ary = ( [ 'a', 'a' ]
, [ 'b', ' b' ]
, 'c'
, 123
);

my $eref = \$ary[1];

for (@ary) {
print $eref, "\t", \$_, "\n";
}

Even better would be to actually delete, not just to undef the
element.

perldoc perlop, look for slice.
 
R

robic0

Michael Goerz schreef:
Oh, so you have a 'poiter' using Perl.....
Maybe this helps:

#!/usr/bin/perl
use strict;
use warnings;

my @ary = ( [ 'a', 'a' ]
, [ 'b', ' b' ]
, 'c'
, 123
);

my $eref = \$ary[1];

for (@ary) {
print $eref, "\t", \$_, "\n";
}

Even better would be to actually delete, not just to undef the
element.

perldoc perlop, look for slice.

Where is the perldoc looking for pointer?
 
C

Charles DeRykus

Michael said:
Hi,

how can I delete from an array by reference (i.e. I already have a
pointer to the array element) instead of by index. Consider the
following code:


#!/usr/bin/perl -w
use strict;
use Data::Dumper;

my $testarray = [
["bla", "bla"],
["xyz", "xyz"],
"blabla",
123 ];

print("before:\n", Dumper($testarray), "\n");

my $pointer_to_element = $testarray->[1];

undef($pointer_to_element); # no effect ...
undef(@{$pointer_to_element}); # has *some* effect,
# but only works since I know
# the element is an array
print("after undef by reference:\n", Dumper($testarray), "\n");

undef(@{$testarray}[1]); # ... but I want the same as this
print("after undef by index:\n", Dumper($testarray), "\n");
Even better would be to actually delete, not just to undef the element.

`delete` semantics differ for arrays and hashes. See: perldoc -f delete.
The `delete` doc needs a tuneup to clarify the difference upfront IMO.

So, the grep filter shown would be the best way but just to illustrate
another way utilizing a hash:

use Tie::IxHash;
my $hash = Tie::IxHash->new( map { ($_, $_) } @$testarray );
$hash->Delete( $pointer_to_element );
$testarray = [ $hash->Values ];
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top