Remove a specific element from an Array

S

Sumit

Hey Guys,

I am a new bie to this Group.
I have a Problem.
I want to remove an element from an array whose index i dont know.
--------------------------------------------------------------------------------------------------

#!/usr/bin/perl -w
use strict;

my @updateNames = ();
my @tempArr = ();
my $item = "";
my $item2 = "";

push @updateNames,"I_love_you";
push @updateNames,"I_love_you_too";
push @updateNames,"I_hate_you";

push @tempArr,"I_love_you";
push @tempArr,"I_love_Him";
push @tempArr,"I_hate_you";

foreach $item (@updateNames)
{
foreach $item2 (@tempArr)
{
if ($item eq $item2)
{
pop @updateNames,$item; #This pop is just removing the
last element i want to remove $item2 from @updateNames
}
}
}

print "\n";
foreach $item (@updateNames)
{
print $item;
print "\n";
}
 
A

anno4000

Sumit said:
Hey Guys,

I am a new bie to this Group.
I have a Problem.
I want to remove an element from an array whose index i dont know.
--------------------------------------------------------------------------------------------------

#!/usr/bin/perl -w
use strict;

my @updateNames = ();
my @tempArr = ();
my $item = "";
my $item2 = "";

push @updateNames,"I_love_you";
push @updateNames,"I_love_you_too";
push @updateNames,"I_hate_you";

push @tempArr,"I_love_you";
push @tempArr,"I_love_Him";
push @tempArr,"I_hate_you";

foreach $item (@updateNames)
{
foreach $item2 (@tempArr)
{
if ($item eq $item2)
{
pop @updateNames,$item; #This pop is just removing the
last element i want to remove $item2 from @updateNames
}
}
}

print "\n";
foreach $item (@updateNames)
{
print $item;
print "\n";
}

That code doesn't compile. Please *run* your code before you post
it to the group. Non-working code is almost useless as a problem
description.
Can somebody help me on this?

It looks like you want to remove the elements from @updateNames that
also appear in @tempArr. If so, it would be better to use a hash
instead of @tempArr. You can the use grep() to remove the unwanted
entries:

my @updateNames = qw( I_love_you I_love_you_too I_hate_you);
my %tempHash;
$tempHash{ $_} = 1 for qw( I_love_you I_love_Him I_hate_you);

@updateNames = grep !$tempHash{ $_}, @updateNames;

print "@updateNames\n";
__END__

Anno
 
P

Peter Makholm

Sumit said:
I am a new bie to this Group.
I have a Problem.
I want to remove an element from an array whose index i dont know.

If you want to remove all elements matching some condition, the you
could use the grep function:

@names = grep { $_ != "Some name" } @names;

If you just want to remove one of the element with some value you'll
have to find the index by searching the list and then use splice to
remove the element.

//Makholm
 
S

Sumit

That code doesn't compile. Please *run* your code before you post
it to the group. Non-working code is almost useless as a problem
description.

I can compile the code, the result is wrong i know but i didn't had
any problem in running the code.

Sumit
 
A

anno4000

Sumit said:
I can compile the code, the result is wrong i know but i didn't had
any problem in running the code.

Oh please... . Look at your code again:

#!/usr/bin/perl -w
use strict;

[snip]

foreach $item (@updateNames)
{

The variable $item is undeclared. Under "strict" that is a fatal error.
What do you hope to gain by making verifiably false statements?

Anno
 
A

anno4000

Sumit said:
I can compile the code, the result is wrong i know but i didn't had
any problem in running the code.

Right, apologies. I lost a declaration or two in copy/paste when I
tried to run it.

Anno
 
P

Paul Lalli

I am a new bie to this Group.
I have a Problem.
I want to remove an element from an array whose index i dont know.

Loop through the array, find the index. Use splice()

my $index;
for my $i (0..$#stuff) {
if ($stuff[$i] eq 'RemoveThis') {
$index = $i;
last;
}
}
splice(@stuff, $index, 0);

perldoc -f splice
for more information

Of course, the real answer to the problem is that you should have been
using a hash to begin with. That is, rather than:
my @stuff = ('foo', 'bar', 'baz');
You should have
my %stuff = (foo => 1, bar => 1, baz => 1);
so that when it comes time to remove "bar", all you have to do is:
delete $stuff{bar};

Paul Lalli
 
J

Jürgen Exner

Sumit said:
I want to remove an element from an array whose index i dont know.
foreach $item (@updateNames) {
foreach $item2 (@tempArr) {
if ($item eq $item2) {
pop @updateNames,$item; #This pop is just removing the
last element i want to remove $item2 from @updateNames

It is a very bad idea to modify an array (add/remove elements) while you are
looping through it.
Can somebody help me on this?

This looks like from @updateNames you want to remove all elements where the
value appears in @tempArr.
Have a look at "perldoc -q intersection":
How do I compute the difference of two arrays? How do I compute the
intersection of two arrays?

jue
 
S

Sumit

This looks like from @updateNames you want to remove all elements where the
value appears in @tempArr.

Yes you are right.
I want to remove all the element of @tempArr if tehy are present in
@updateNames.
Have a look at "perldoc -q intersection"

sumit: perldoc -q intersection
No documentation found for "perlfaq1".
No documentation found for "perlfaq2".
No documentation found for "perlfaq3".
No documentation found for "perlfaq4".
No documentation found for "perlfaq5".
No documentation found for "perlfaq6".
No documentation found for "perlfaq7".
No documentation found for "perlfaq8".
No documentation found for "perlfaq9".
How do I compute the difference of two arrays? How do I compute the
intersection of two arrays?

Searching....

Thanks
Sumit
 
P

Paul Lalli

sumit: perldoc -q intersection
No documentation found for "perlfaq1".
No documentation found for "perlfaq2".
No documentation found for "perlfaq3".
No documentation found for "perlfaq4".
No documentation found for "perlfaq5".
No documentation found for "perlfaq6".
No documentation found for "perlfaq7".
No documentation found for "perlfaq8".
No documentation found for "perlfaq9".

Your installation of Perl is broken. Contact your system
administrator to have them fix it.
Searching....

http://perldoc.perl.org/search.html?q=intersection

Paul Lalli
 
G

Greg Bacon

: I want to remove an element from an array whose index i dont know.

Let's first look at your code from a bottom-up perspective:

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

This is a good habit. These days, people tend to drop the -w
switch and use the warnings pragma instead, as in

#! /usr/bin/perl

use warnings;
use strict;

: my @updateNames = ();
:
: push @updateNames,"I_love_you";
: push @updateNames,"I_love_you_too";
: push @updateNames,"I_hate_you";

Arrays start out empty, so the assignments aren't strictly necessary.
There are cases where you might want to be explicit for purposes of
emphasis.

In your case, you explicitly set @updateNames to the empty list and
then push values onto it. You can initialize arrays when you declare
them, as in

my @updateNames = (
"I_love_you",
"I_love_you_too",
"I_hate_you",
);

: foreach $item (@updateNames)
: {
: foreach $item2 (@tempArr)
: {
: if ($item eq $item2)
: {
: pop @updateNames,$item;
: }
: }
: }

Someone else already noted (but it doesn't hurt to repeat!) that
you shouldn't modify a collection while you're iterating over it.

The pop operator doesn't work the way you seem to think it does.
(With warnings enabled, you should have seen "Useless use of private
variable in void context" about that line.)

With pop, you supply an array as its only operand, and the result
is that the array's last element (if any) disappears.

: print "\n";
: foreach $item (@updateNames)
: {
: print $item;
: print "\n";
: }

Now from the top-down: at a high level, what are you trying to do?

Do you want to print all elements in @updateNames that are not in
@tempArr? If so, you can simplify your code:

#! /usr/bin/perl

use warnings;
use strict;

my @updateNames = (
"I_love_you",
"I_love_you_too",
"I_hate_you",
);

my %exclude;
$exclude{$_}++ for (
"I_love_you",
"I_love_Him",
"I_hate_you",
);

foreach my $item (@updateNames)
{
print $item, "\n" unless $exclude{$item};
}

As a helpful hint, prefer to search hashes over arrays.

I hope this helps,
Greg
 
T

Tad McClellan

Petr Vileta said:
Tad said:
Petr Vileta said:
Sumit wrote:
#!/usr/bin/perl -w
if (@updateNames[$item] eq $item2)


You should not ignore the warnings that perl issues.
Well, sorry ;-) Should be

if ($updateNames[$item] eq $item2)

but on my Perl 5.6.1 work well both forms ;-)


Sometimes it doesn't make a difference, but sometimes it does.


See:

perldoc -q difference

What is the difference between $array[1] and @array[1]?
 
D

Dr.Ruud

Petr Vileta schreef:
foreach $item (0..$#updateNames)
{
foreach $item2 (@tempArr)
{
if (@updateNames[$item] eq $item2)
{
splice @updateNames, $item, 1;

I think it is better to undef the array element here,
and then remove the undefined elements by a grep, after the loop.
 
A

anno4000

Dr.Ruud said:
Petr Vileta schreef:
foreach $item (0..$#updateNames)
{
foreach $item2 (@tempArr)
{
if (@updateNames[$item] eq $item2)
{
splice @updateNames, $item, 1;

I think it is better to undef the array element here,
and then remove the undefined elements by a grep, after the loop.

Right. The code above may *seem* to work in some cases but won't
in others. On the other hand, using undef as a marker only works
if the original array elements are all defined. Collecting the
indices and deleting the elements in reverse order after the loop
is a solution, but we have seen better ones in this thread.

Anno
 

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

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top