Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Best way to remove elem of for loop

by rjt (Curate)
on Apr 24, 2014 at 16:47 UTC ( [id://1083648]=note: print w/replies, xml ) Need Help??


in reply to Best way to remove elem of for loop

Of the solutions already posted, none of them seem to address the fact that you also wanted to print an error message when removing one of the elements from the list. Here's an elegant way to do that:

my @dirs = qw#/usr /tmp Kitten.gif /sys /var/run /nonexistent /root#; @dirs = map { warn "`$_' is not a directory\n" if not -d; -d _ ? $_ : () } @dirs; print "\nThe following are valid: @dirs\n";

Output:

`Kitten.gif' is not a directory `/nonexistent' is not a directory The following are valid: /usr /tmp /sys /var/run /root

The major point of learning, here, is probably the fact that map uses the result of the last statement in the block: in this case, the result of the conditional operator: either the directory name, or an empty list, if it's not a directory.

Edit: Thanks RonW for reminding me of _. I left my original paragraph below the <readmore> for continuity's sake, but have updated the code above—and had my 1st cup of coffee.

(Previous sub-optimal advice, no longer applicable to the above code): Yes, I use the -d test twice, but my reasoning is, it's cleaner, and the (very) slight hit to efficiency is only really going to be noticeable on extremely slow and non-cached media or extremely large lists of directories (and even then I'm not sure without a benchmark). If that's of particular concern, you can always do my $is_dir = -d; and use that instead.

use strict; use warnings; omitted for brevity.

Replies are listed 'Best First'.
Re^2: Best way to remove elem of for loop
by RonW (Parson) on Apr 24, 2014 at 17:26 UTC

    If you do -d _ the second time, the test will use the fstat buffer from the first time rather than make another syscall.

Re^2: Best way to remove elem of for loop
by johngg (Canon) on Apr 24, 2014 at 23:04 UTC

    You could use a do block to avoid having the -d directory test twice.

    $ ls -F fred testFBF* xxx/ yyy/ $ perl -Mstrict -Mwarnings -E ' my @dirs = qw{ fred testFBF xxx yyy }; @dirs = map { -d $_ ? $_ : do { warn qq{Not a directory: $_\n}; () } } @dirs; say qq{Directories: @dirs};' Not a directory: fred Not a directory: testFBF Directories: xxx yyy $

    I hope this is of interest.

    Cheers,

    JohnGG

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-04-19 17:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found