Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Deleting specific array elements

by joec_ (Scribe)
on Nov 26, 2008 at 09:42 UTC ( [id://726049]=perlquestion: print w/replies, xml ) Need Help??

joec_ has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Maybe i'm being exceptionally stupid :P but how does one go about deleting a specific element from an array? I have the following code:

foreach $mol (@molecules) {
     if ($mol eq "\n"){
          splice (@molecules, scalar($mol),1);
     }
}

So, i would like to delete any elements in @molecules (array created via split) that contain elements with just new lines in. When i run it, i get Argument "\n" isn't numeric in splice

Any help or advice appreciated

Thanks -- Joe.

Replies are listed 'Best First'.
Re: Deleting specific array elements
by salva (Canon) on Nov 26, 2008 at 09:47 UTC
    Probably, the easiest way is to use grep:
    @molecules = grep { $_ ne "\n" } @molecules;

      If your array is too big to copy it, try something like this:

      for my $m (reverse 0 .. $#molecules) { if ($molecules[$m] eq "\n"){ splice (@molecules, $m, 1); } }
        That's very inefficient, O(N^2) worst case under the hood. If your data is so big it doesn't fits in memory, it is not a good solution either. Note also, that the grep solution is swap-friendly as it access memory in a sequential manner.

        Anyway, if you want to minimize memory usage and still be O(N):

        my $to = 0; for (@m) { $m[$to++] = $_ if $_ ne "\n"; } splice @m, $to;
        Unfortunally, if the array is large, and there's a significant number of elements "\n" in the array, the repeated splicing can be slow. splice() is an O(n) operation (with n the length of the array), and that's a tight worst case bound (splice may require shifting half the array). If you have a large array, and cannot afford to copy, you can still remove the offending elements in situ:
        my $j = 0; for (my $i = 0; $i < @molecules; $i ++) { $molecules[$j++] = $molecules[$i] unless $molecules[$i] eq "\n"; } splice @molecules, $j;
Re: Deleting specific array elements
by moritz (Cardinal) on Nov 26, 2008 at 09:48 UTC
    If $mol eq "\n" then scalar($mol) is still \n, and not a number. But splice expects a number as second (and third) argument.

    A more idiomatic way to remove newlines is

    @molecules = grep { $_ ne "\n" } @molecules;
Re: Deleting specific array elements
by hexcoder (Curate) on Nov 26, 2008 at 10:09 UTC
    If you never need these newline elements, i would avoid storing them in the first place.
    @molecules = grep { $_ ne "\n" } split ...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://726049]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2024-04-20 14:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found