http://www.perlmonks.org?node_id=983254

programmer.perl has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I'm having trouble with a deleting the element of an array, here I'm attaching the output (error in the last line, if you see there are two commas), it seems that element is not being deleted, instead it's undefined (func. undef). How to delete the element (from memory)? I tried to look into perldoc but I couldn't find another functions except 'delete' and 'undef'. Here in perldoc about 'delete' : WARNING: Calling delete on array values is deprecated and likely to be removed in a future version of Perl.

Output of program:

Here are the statistics for the Sino. Address: kk ID: kk <...continues...> Course(s): Chem, Bio, Maths, C++, Java After dropping: Chem, Bio, Maths, , Java

Code of program and module:

package Student3; sub new { my $class = shift; my $ref = {}; # Anonymous hash bless($ref, $class); return $ref; } sub set_student { my $self = shift; <...continues...> print "Enter the student's course(s) delimiting them with a comma (,) "; chomp(my $cour = <STDIN>); $cour =~ s/\s+//g; my @cour = split(",", $cour); chomp($self->{"Course(s)"}->{"cour"}=[@cour]); <...continues here...> } <...continues...> sub drop_courses { my $self=shift; my $del_cour = shift; # $student1->drop_courses(["C++"]); my $num = @{$del_cour}; if ($num == 1) { foreach $k (@{$self->{'Course(s)'}->{'cour'}}) { if ($k eq $del_cour->[0]) { $k=""; } } } print "After dropping: ", join (", ", @{$self->{'Course(s)'}->{'cour'}}), "\n"; 1;

The code of a program

#!/usr/bin/perl -w use Student3; use warnings; use strict; my $student1 = Student3->new; $student1->set_student; $student1->show_student; $student1->add_courses(["C++", "Java"]); $student1->show_student; $student1->drop_courses(["C++"]);

Replies are listed 'Best First'.
Re: deleting from the memory
by davido (Cardinal) on Jul 23, 2012 at 23:33 UTC

    To remove array elements from the lefthand side of an array one at a time, use shift. To do the same from the righthand side, use pop. If you need to add or remove one or more elements from anywhere in the array, use splice. As you've discovered, delete just undefines the value. splice can actually remove the elements and shift all subsequent elements up into place.

    However, keep in mind that every time you call splice to remove elements from the middle of an array, you're performing an O(n) operation. If it's a large enough array, and you do it often enough, you might consider rethinking your algorithm. A hash would provide O(1) adds and deletes, though you would lose all notion of sortedness (and it would be silly to eliminate an O(n) operation and trade it for a O(n log n) sort).


    Dave

Re: deleting from the memory
by roboticus (Chancellor) on Jul 23, 2012 at 23:48 UTC

    programmer.perl:

    As davido mentions, deleting from a *large* list may be a bit slow. The algorithm I use (only works when the order isn't important) is to copy the last item in the list on top of the entry to delete, and then truncate the last item from the list:

    #!/usr/bin/perl + use strict; use warnings; use Data::Dumper; my @stuff = (qw(Chem Bio Maths C++ Java)); print "BEFORE: ", join(", ", @stuff), "\n"; my $i = int(@stuff * rand); print "Removing item $i\n"; if ($i != $#stuff) { $stuff[$i] = $stuff[-1]; } $#stuff = $#stuff-1; print "AFTER: ", join(", ", @stuff), "\n";

    Running this a few times gives me:

    $ perl t.pl BEFORE: Chem, Bio, Maths, C++, Java Removing item 4 AFTER: Chem, Bio, Maths, C++ $ perl t.pl BEFORE: Chem, Bio, Maths, C++, Java Removing item 2 AFTER: Chem, Bio, Java, C++ $ perl t.pl BEFORE: Chem, Bio, Maths, C++, Java Removing item 3 AFTER: Chem, Bio, Maths, Java

    Update: Forgot some brackets (on davidos name ... almost did it again!)

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: deleting from the memory
by kcott (Archbishop) on Jul 24, 2012 at 00:42 UTC

    You asked the same question a matter of hours ago: Re^4: Nested Data Structures, OOP.

    To which, I've just replied: Re^5: Nested Data Structures, OOP.

    Now you have your answers spread across two threads and lose any collaborative benefits from posting in a single thread.

    If you have not received an answer in a reasonable time, at least indicate that you are reposting and provide a link to the original.

    This is a global site with Monks in most, if not all, 24 time zones. I personally do not consider 9 hours to be a reasonable time: I'd probably wait at least 24 hours before reposting if I'd received no reponses.

    -- Ken

      I will consider this. I hurried up, I didn't want to break the general rule... I will consider this and in future it will not be happen :)