Remove a specific element from an Array

Discussion in 'Perl Misc' started by Sumit, Jul 9, 2007.

  1. Sumit

    Sumit Guest

    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";
    }


    --------------------------------------------------------------------------------------------------

    Can somebody help me on this?

    --
    Sumit
     
    Sumit, Jul 9, 2007
    #1
    1. Advertising

  2. Sumit

    -berlin.de Guest

    Sumit <> wrote in comp.lang.perl.misc:
    > 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
     
    -berlin.de, Jul 9, 2007
    #2
    1. Advertising

  3. Sumit <> writes:

    > 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
     
    Peter Makholm, Jul 9, 2007
    #3
  4. Sumit

    Sumit Guest

    > 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
     
    Sumit, Jul 9, 2007
    #4
  5. Sumit

    -berlin.de Guest

    Sumit <> wrote in comp.lang.perl.misc:
    > > 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.


    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
     
    -berlin.de, Jul 9, 2007
    #5
  6. Sumit

    -berlin.de Guest

    Sumit <> wrote in comp.lang.perl.misc:
    > > 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.


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

    Anno
     
    -berlin.de, Jul 9, 2007
    #6
  7. Sumit

    Paul Lalli Guest

    On Jul 9, 3:44 am, Sumit <> wrote:
    > 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
     
    Paul Lalli, Jul 9, 2007
    #7
  8. Sumit wrote:
    > 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
     
    Jürgen Exner, Jul 9, 2007
    #8
  9. Sumit

    Sumit Guest


    > 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
     
    Sumit, Jul 9, 2007
    #9
  10. Sumit

    Paul Lalli Guest

    On Jul 9, 10:54 am, Sumit <> wrote:

    > > 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".


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

    > > How do I compute the difference of two arrays? How do I compute the
    > > intersection of two arrays?

    >
    > Searching....


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

    Paul Lalli
     
    Paul Lalli, Jul 9, 2007
    #10
  11. Sumit

    Greg Bacon Guest

    In article <>,
    Sumit <> wrote:

    : 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
    --
    This is the golden rule of fractional reserve banking: Do unto
    depositors before the depositors do it unto you.
    -- Gary North
     
    Greg Bacon, Jul 9, 2007
    #11
  12. Petr Vileta <> wrote:
    > Sumit wrote:


    >> #!/usr/bin/perl -w


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



    You should not ignore the warnings that perl issues.

    They often point out a bug in your code...


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
     
    Tad McClellan, Jul 11, 2007
    #12
  13. Petr Vileta <> wrote:
    > Tad McClellan wrote:
    >> Petr Vileta <> wrote:
    >>> 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]?


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
     
    Tad McClellan, Jul 11, 2007
    #13
  14. Sumit

    Dr.Ruud Guest

    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.

    > }
    > }
    > }


    --
    Affijn, Ruud

    "Gewoon is een tijger."
     
    Dr.Ruud, Jul 11, 2007
    #14
  15. Sumit

    -berlin.de Guest

    Dr.Ruud <> wrote in comp.lang.perl.misc:
    > 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
     
    -berlin.de, Jul 12, 2007
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    4
    Views:
    2,535
  2. HANM
    Replies:
    2
    Views:
    723
    Joseph Kesselman
    Jan 29, 2008
  3. mazdotnet
    Replies:
    2
    Views:
    400
    Alexey Smirnov
    Oct 2, 2009
  4. sdfgsd
    Replies:
    3
    Views:
    291
    sdfgsd
    Nov 4, 2003
  5. nmvega
    Replies:
    1
    Views:
    165
Loading...

Share This Page