Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Sort routine

by Anonymous Monk
on Sep 18, 2002 at 11:38 UTC ( #198794=perlquestion: print w/replies, xml ) Need Help??

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


I have an array like the following:

@event_queue = ("$time\tEvent 1", "$time\tEvent 5", "$time\tEvent 3";

My array will grow to probably 100 elements, with the time element increasing at random, and I want to sort the array in ascending order based on the time portion.

This is currently what I'm doing
@event_queue = sort { $a <=> $b } @event_queue;

This doesn't seem to work, I'm trying to ignore the Event portion of the array, and sort based on the time portion.

Any suggestions?

Replies are listed 'Best First'.
Re: Sort routine
by Abigail-II (Bishop) on Sep 18, 2002 at 11:45 UTC
    Assuming the $time part is a Unix timestamp, and all stamps are from after Sun Sep 9 01:46:39 2001, you could simply do: @event_queue = sort @event_queue.

    Otherwise, it depends on the format of $time.


      $time isn't a unix time stamp, it's a simple 3 unit time increment (i.e. 3,6,9,)
        Then you can use a Guttman-Rosler Transform (GRT) or a Schwarzian Transform (ST) in a straightforward way. A search on this site should reveal many examples.


Re: Sort routine
by RMGir (Prior) on Sep 18, 2002 at 12:02 UTC
    You've got a few options. You can change how you store your data, storing your time values with 0 padding, like this:
    sub makeEvent { sprintf("%08d\t%s",@_); } @event_queue = (makeEvent($time,"Event 1"), makeEvent($time,"Event 5") +, makeEvent($time,"Event 5")); # now this works fine! @event_queue=sort @event_queue;
    That's actually a variant of a technique called the Guttman Rossler Transform; in the GRT you'd encode your times just before sorting, and decode them after you're done. But if you can just keep them in sortable form all along, life is simpler.

    The other alternative is the Schwartzian Transform, which is a fraction less efficient, but will still do the job very well...

    @event_queue = map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [$_, (split/\t/)[0]] } @event_queue;
    The trick here is that the time values are extracted, and then compared as integers to get things in the right order. Then the strings that were associated with those integers are returned by the top map call.
Re: Sort routine
by dada (Chaplain) on Sep 18, 2002 at 11:56 UTC
    this seems a perfect case for a Schwartzian Transform:
    @event_queue = map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [$_, split /\t/, $_, 1] } @event_queue;

    King of Laziness, Wizard of Impatience, Lord of Hubris

      You do, of course, mean map { [$_, split /\t/, $_, 2] }

      Makeshifts last the longest.

Re: Sort routine
by Anonymous Monk on Sep 18, 2002 at 12:18 UTC
    Thanks guys (and gals),

    I've never used the transform method, but it works very well, and this is definitely worth commiting to memory.

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2022-06-29 04:40 GMT
Find Nodes?
    Voting Booth?
    My most frequent journeys are powered by:

    Results (94 votes). Check out past polls.