I would suggest that you should loop through your list of entries, and push onto a separate list those which are directories. Or, simply use a File::Find loop (instead of building an array of things, which consumes memory arbitrarily), and push directories onto the array as they are found. (“Millions of files” would result in “a big phat array,” with the thrashing-induced slowdowns that such a thing might produce, whereas there probably aren’t “millions of directories.”)
Yes, it is perfectly reasonable to “mark things,” too, and then to loop back through looking for things that are not so marked. Thus, your approach of zapping the names that are not directories is a legitimate approach. However, I would set the element to undef, since you only need to get rid of the value that is now there; you need not conjure up an empty-string value to replace it. The “marking” approach avoids the issue of diddling with an array while you are looping through one, which in general is never prudent to do.