How does Perl sort array in opendir by default?

Discussion in 'Perl Misc' started by Mike, Jan 15, 2004.

  1. Mike

    Mike Guest

    I'm using opendir to open a series of files in a directory, but
    they're not being sorted by default the way I thought they would.

    I have 3 files:
    aaa.txt (765 bytes)
    bbb.txt (977 bytes)
    ccc.txt (10161 bytes)

    I assumed that it would enter them into the array alphabetically, but
    instead they went in ccc,aaa,bbb!

    Is there a method to this madness? Coincidentally, it's being sorted
    exactly like I want right now, but I'm not sure what will happen when
    a 4th file is added.

    TIA,

    Mike


    PS, the exact code is:

    opendir FILENAMES, "$basepath";
    @data= readdir FILENAMES;
    closedir FILENAMES;
    Mike, Jan 15, 2004
    #1
    1. Advertising

  2. Mike

    Uri Guttman Guest

    >>>>> "M" == Mike <> writes:

    M> I'm using opendir to open a series of files in a directory, but
    M> they're not being sorted by default the way I thought they would.

    M> I assumed that it would enter them into the array alphabetically, but
    M> instead they went in ccc,aaa,bbb!

    where did you read in the docs that this was the case? or who taught you
    that mistaken factoid?

    perldoc -f readdir doesn't mention the term sort. did you check out that
    doc before you made public your incorect assumption?

    and there was a thread on this in the last week. try googling for it

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jan 15, 2004
    #2
    1. Advertising

  3. On Wed, 14 Jan 2004 23:29:58 -0800, Mike wrote:

    > I assumed that it would enter them into the array alphabetically


    Why did you assume that? Nothing in the docs for readdir says anything
    about them being sorted.

    If you want them sorted, you have to sort them yourself; for a simple
    alphabetic sort, this could be as simple as:

    my @files = sort(readdir(FILENAMES));

    sherm--
    Sherm Pendley, Jan 15, 2004
    #3
  4. Mike

    Mike Guest

    > > I assumed that it would enter them into the array alphabetically
    >
    > Why did you assume that? Nothing in the docs for readdir says anything
    > about them being sorted.


    I knew that perldoc didn't say anything, I was just making an
    assumption because my server lists all of the files alphabetically by
    default when you telnet in. Plus, I had no other reason to believe
    otherwise. Just an assumption.

    > If you want them sorted, you have to sort them yourself; for a simple
    > alphabetic sort, this could be as simple as:
    >
    > my @files = sort(readdir(FILENAMES));


    Of course, which would sort them alphabetically, or whatever you make
    it do. In this case, I would prefer them to be sorted by
    last-date-modified, and that's why I ask; if this is how they're
    sorted by default, then there's no need for me to code it.

    To Uri (who also replied), when I searched for "sort opendir array,"
    the most recent post to come up was from 2002. Can you be more
    specific about the similar recent post?

    Mike
    Mike, Jan 15, 2004
    #4
  5. Mike

    Paul Lalli Guest

    On Thu, 15 Jan 2004, Mike wrote:

    > > If you want them sorted, you have to sort them yourself; for a simple
    > > alphabetic sort, this could be as simple as:
    > >
    > > my @files = sort(readdir(FILENAMES));

    >
    > Of course, which would sort them alphabetically, or whatever you make
    > it do. In this case, I would prefer them to be sorted by
    > last-date-modified, and that's why I ask; if this is how they're
    > sorted by default, then there's no need for me to code it.
    >
    > To Uri (who also replied), when I searched for "sort opendir array,"
    > the most recent post to come up was from 2002. Can you be more
    > specific about the similar recent post?
    >


    untested:

    my @files = sort {-M $a <=> -M $b} readdir(FILENAMES);


    This puts the most recently modified at the beginning of the list. For
    the reverse, swap $a and $b above.

    The default is whatever order they are returned by your operating system.
    This could changed depending on what system your script is run on.
    Therefore, trusting the default to be what you want is A Bad Idea.

    Paul Lalli
    Paul Lalli, Jan 15, 2004
    #5
  6. In article <>,
    Paul Lalli <> wrote:
    :untested:

    :my @files = sort {-M $a <=> -M $b} readdir(FILENAMES);


    :This puts the most recently modified at the beginning of the list.

    Schwartzian Transform unless you don't mind exponential numbers of
    stat()'s.

    --
    I wrote a hack in microcode,
    with a goto on each line,
    it runs as fast as Superman,
    but not quite every time! -- Don Libes et al.
    Walter Roberson, Jan 15, 2004
    #6
  7. >>>>> "Mike" == Mike <> writes:

    Mike> I knew that perldoc didn't say anything, I was just making an
    Mike> assumption because my server lists all of the files alphabetically by
    Mike> default when you telnet in. Plus, I had no other reason to believe
    Mike> otherwise. Just an assumption.

    But "ls" is doing the sorting. If you give ls the -f switch, it
    presents unsorted. Also, find shows you the unsorted order as well.

    readdir() returns the results unsorted because sorting is extra work,
    and if you're going to do something to every element anyway, it doesn't
    matter what order. :)

    print "Just another Perl hacker,"

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
    Randal L. Schwartz, Jan 15, 2004
    #7
  8. Also sprach Walter Roberson:

    > In article <>,
    > Paul Lalli <> wrote:
    >:untested:
    >
    >:my @files = sort {-M $a <=> -M $b} readdir(FILENAMES);
    >
    >
    >:This puts the most recently modified at the beginning of the list.
    >
    > Schwartzian Transform unless you don't mind exponential numbers of
    > stat()'s.


    Exponential?

    Tassilo
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
    Tassilo v. Parseval, Jan 15, 2004
    #8
  9. Mike

    Paul Lalli Guest

    On Thu, 15 Jan 2004, Walter Roberson wrote:

    > In article <>,
    > Paul Lalli <> wrote:
    > :untested:
    >
    > :my @files = sort {-M $a <=> -M $b} readdir(FILENAMES);
    >
    >
    > :This puts the most recently modified at the beginning of the list.
    >
    > Schwartzian Transform unless you don't mind exponential numbers of
    > stat()'s.
    >


    Quite correct. I should have done it with a transform in the first place:

    (still untested):

    my @files = map { $_->[0] }
    sort { $a->[1] <=> $b->[1] }
    map { [ $_, -M ] }
    readdir FILENAMES;


    Paul Lalli.
    Paul Lalli, Jan 15, 2004
    #9
  10. Mike

    pkent Guest

    In article <>,
    (Mike) wrote:

    > I'm using opendir to open a series of files in a directory, but
    > they're not being sorted by default the way I thought they would.


    Sorry to break it to you but computers have a habit of sucking, and of
    not doing what you want them to. Or even worse, doing exactly what you
    tell them to. :)

    You said that the computer didn't do what you thought it'd do. Even
    perldoc -f readdir doesn't mention the order of entries (on my system at
    least). But perl can help, using the sort() function built in to perl -
    e.g.:

    @filenames = sort @filenames;

    for the default sorting order. If that's not good for you, you can
    define your own sorting routine.

    P

    --
    pkent 77 at yahoo dot, er... what's the last bit, oh yes, com
    Remove the tea to reply
    pkent, Jan 15, 2004
    #10
  11. In article <bu6sck$t93$-Aachen.DE>,
    Tassilo v. Parseval <-aachen.de> wrote:
    :Also sprach Walter Roberson:
    :> Schwartzian Transform unless you don't mind exponential numbers of
    :> stat()'s.

    :Exponential?

    For small exponents ;-)

    perldoc on sort says that it used to use quicksort, worst case O(N**2),
    and now uses a mergesort, worst case O(N * log N) unless you request
    quicksort specifically.
    --
    Are we *there* yet??
    Walter Roberson, Jan 15, 2004
    #11
  12. Mike <> wrote:

    > Subject: How does Perl sort array in opendir by default?



    Perl does not determine what order they are in.

    The Operating System determines what order they are in.


    > PS, the exact code is:
    >
    > opendir FILENAMES, "$basepath";



    You should check the return value from opendir().

    You should NOT use useless double quotes.


    opendir FILENAMES, $basepath or die "could not open '$basepath' dir $!";


    > @data= readdir FILENAMES;



    @data= sort readdir FILENAMES;


    We gotta kind of wonder why you couldn't come up with that yourself...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jan 15, 2004
    #12
  13. Mike wrote:
    >>>I assumed that it would enter them into the array alphabetically

    >>
    >>Why did you assume that? Nothing in the docs for readdir says anything
    >>about them being sorted.

    >
    >
    > I knew that perldoc didn't say anything, I was just making an
    > assumption because my server lists all of the files alphabetically by
    > default when you telnet in.


    I presume you mean when you use an ls command. A "man ls" would
    reveal that the documentation *tells* you ls sorts by filename by
    default.

    > Plus, I had no other reason to believe
    > otherwise. Just an assumption.


    Why would you assume that? The documentation makes no mention
    of how the entries will be ordered. Therefore the only reasonable
    way to proceed is not to assume *anything* about how the entries
    will be ordered.

    >
    >
    >>If you want them sorted, you have to sort them yourself; for a simple
    >>alphabetic sort, this could be as simple as:
    >>
    >>my @files = sort(readdir(FILENAMES));

    >
    >
    > Of course, which would sort them alphabetically, or whatever you make
    > it do. In this case, I would prefer them to be sorted by
    > last-date-modified, and that's why I ask; if this is how they're
    > sorted by default, then there's no need for me to code it.


    It's not sorted any way by default. If you want a specific ordering,
    you're going to have to do it yourself.

    Chris Mattern
    Chris Mattern, Jan 16, 2004
    #13
  14. Also sprach Walter Roberson:

    > In article <bu6sck$t93$-Aachen.DE>,
    > Tassilo v. Parseval <-aachen.de> wrote:
    >:Also sprach Walter Roberson:
    >:> Schwartzian Transform unless you don't mind exponential numbers of
    >:> stat()'s.
    >
    >:Exponential?
    >
    > For small exponents ;-)
    >
    > perldoc on sort says that it used to use quicksort, worst case O(N**2),
    > and now uses a mergesort, worst case O(N * log N) unless you request
    > quicksort specifically.


    Ah, well. Exponential would be something like O(2^n). I think you meant
    to say quadratic instead.

    Tassilo
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
    Tassilo v. Parseval, Jan 16, 2004
    #14
  15. Mike

    Bart Lateur Guest

    Mike wrote:

    >Is there a method to this madness?


    It is sorted in order of physical appearance in the on-disk directory
    listing structure. So it's nothing you can really use.

    --
    Bart.
    Bart Lateur, Jan 17, 2004
    #15
  16. In article <>,
    Bart Lateur <> wrote:
    :Mike wrote:

    :>Is there a method to this madness?

    :It is sorted in order of physical appearance in the on-disk directory
    :listing structure. So it's nothing you can really use.

    No it isn't; on UNIX systems, it's sorted in the readdir() order,
    which is free to skip back and forth through the physical entries.
    For example, if the directory used a tree structure, the distance from
    the physical beginning of the block might reflect the number of N-ary
    decisions whereas readdir() order might thread the leaves of the tree.
    --
    "Infinity is like a stuffed walrus I can hold in the palm of my hand.
    Don't do anything with infinity you wouldn't do with a stuffed walrus."
    -- Dr. Fletcher, Va. Polytechnic Inst. and St. Univ.
    Walter Roberson, Jan 17, 2004
    #16
  17. Mike

    Joe Smith Guest

    Mike wrote:

    >>>I assumed that it would enter them into the array alphabetically

    >>
    >>Why did you assume that? Nothing in the docs for readdir says anything
    >>about them being sorted.

    >
    > I knew that perldoc didn't say anything, I was just making an
    > assumption because my server lists all of the files alphabetically by
    > default when you telnet in.


    Strictly speaking, it is not the server that lists the files.
    It is one or more programs on the server that lists the files.
    The `ls` and `dir` programs are documented to explictly
    alphabetize unless told otherwise. Try `ls -f` to see files
    listed in directory order.
    -Joe
    --
    I love my TiVo - http://www.inwap.com/u/joe/tivo/
    Joe Smith, Jan 19, 2004
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andrew

    opendir()

    Andrew, Sep 3, 2003, in forum: Perl
    Replies:
    2
    Views:
    9,450
    John Bokma
    Sep 3, 2003
  2. Bob Gervais

    opendir and if -d $files problem

    Bob Gervais, Nov 7, 2003, in forum: Perl
    Replies:
    1
    Views:
    1,625
    Steve Grazzini
    Nov 12, 2003
  3. Navin
    Replies:
    1
    Views:
    668
    Ken Schaefer
    Sep 9, 2003
  4. theo22
    Replies:
    12
    Views:
    382
    Anno Siegel
    Jan 21, 2004
  5. JJ
    Replies:
    3
    Views:
    290
    Josef Moellers
    Nov 25, 2004
Loading...

Share This Page