Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: Producing 2 lists from a grep call

by tstock (Curate)
on Jun 16, 2002 at 20:03 UTC ( [id://174968]=note: print w/replies, xml ) Need Help??


in reply to Producing 2 lists from a grep call

You can use a while loop around the readdir call, and push the files into your @files, @dirs arrays using a if, elsif, else construct. no need for intermediary @all.

If you don't like this solution for being too simple or verbose, then you could always play with map in void context and the ? : switches.

tstock

Replies are listed 'Best First'.
Re^2: Producing 2 lists from a grep call
by Aristotle (Chancellor) on Jun 16, 2002 at 21:11 UTC
    No need for a void map.
    for (readdir DIR) { next if $_ eq "." or $_ eq ".."; next unless -d "$base/$_" or -f _; push @{ -d _ ? \@dirs : \@files }, $_; }
    Update: Excellent point by particle++. Code updated accordingly.

    Makeshifts last the longest.

      I quite like that one. I came close to that but missed (actually, simply wasn't aware of) the @{\@array) 'trick'.

      However (you knew that was coming right?), as I can do:

      my (@a1,@a2) = ([1,2,3],[3,2,1]);

      Update: the above line doesn't work after all

      I had tried:

      my (@a1,@a2) = ([1,2,3,4,5,6,7],[7,6,5,4,3,2,1]); print Dumper(@a1), Dumper(@a2);

      which gave:

      $VAR1 = [ 1, 2, 3, 4, 5, 6, 7 ]; $VAR2 = [ 7, 6, 5, 4, 3, 2, 1 ];
      which certainly lookedlike it had worked! It was only after seeing this that I went back and added a couple of labels

      print "a1\n", Dumper(@a1), "a2\n", Dumper(@a2);

      That I saw what tstock meant below.

      Thanks tstock, I'll be more careful in future with my quick tests. (I agree about the loop/if being better too.)

      end of update

      Which personally I find a very clear yet concise way of declaring and initialising two arrays. It still seems as if something close to:

      my ( @dirs, @files)= ( @{-d}, @{-f} ) for (readdir DIR);

      could be possible if I could only get the syntactic sugar right!

      This is only an exercise in my trying to understand arrays and list contexts etc. ie. Its essentially a purely academic excercise for late (for me) on a Sunday evening, and so not worthy of anyone's time unless they are also in play mode.

        However (you knew that was coming right?), as I can do:
        my (@a1,@a2) = ([1,2,3],[3,2,1]);

        This doesn't work, sorry. You get @a1 with two array references and @a2 undefined.

        tstock

        Update : This is your one liner: (someone please -- me down for posting this)
        map { ($_ ne '.') && ($_ ne '..') && push @{ -d "$base/$_" ? \@dirs : \@files }, $_ } (readdir DIR);
        I think we can agree that the FOR LOOP/IF STATEMENT is probably a nicer solution ? :)
      this code does not work -- !-d  !=  -f!

      to implement this code properly, you must test for both -d, and -f, and ignore the rest. add next unless -d $_ or -f _; before the push statement and you'll have what you're looking for.

      for (readdir DIR) { next if $_ eq '.' or $_ eq '..'; next unless -d $base . '/' . $_ or -f _; push @{ -d $base . '/' . $_ ? \@dirs : \@files }, $_; }
      Update: changes as per Screamer

      Update 2: for more info on filetests, see -X under perlfunc

      ~Particle *accelerates*

        next unless -d $_ or -f _; Careful, it's "$base/$_". Excellent point though.

        Makeshifts last the longest.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (7)
As of 2024-04-18 07:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found