Your skill will accomplishwhat the force of many cannot PerlMonks

### Re: Sorting dates with the Schwartzian Transform

by ikegami (Pope)
 on Aug 03, 2011 at 18:21 UTC ( #918353=note: print w/replies, xml ) Need Help??

in reply to Sorting dates with the Schwartzian Transform

A Schwartzian Transform when all you have to do is parse dates? That will make things *slower*. Creating all those arrays and references adds up.

This could speed up the sorting (because it creates few extra variables and it uses the specially optimised \$a cmp \$b callback):

```my @sorted =
map substr(\$_, 8),
sort
map join('', (/(..)-(..)-(....)/)[2,1,0], \$_),
@dates;  # DD-MM-YYYY

Naïve:

```my @sorted =
sort {
join('', (\$a =~ /(..)-(..)-(....)/)[2,1,0])
cmp
join('', (\$b =~ /(..)-(..)-(....)/)[2,1,0])
}
@dates;  # DD-MM-YYYY

Schwartzian Transform:

```my @sorted =
map \$_->[0],
sort { \$a->[1] cmp \$b->[1] }
map [ \$_, join('', (/(..)-(..)-(....)/)[2,1,0]) ],
@dates;  # DD-MM-YYYY

Replies are listed 'Best First'.
Re^2: Sorting dates with the Schwartzian Transform
by Wobbel (Acolyte) on Aug 03, 2011 at 19:11 UTC

Dear Perl experts, thanks for all the usefull replies and different approaches! The PerlMonks website is a real good place to learn new things and why you choose a certain solution. Great.

The sorting is not only about dates. Patient_ID, Course_ID, Session_number, Session_date, Imaging_type, and a lot of measurements. The sorting question is the last part of a bigger project. "The doctor" needs the data in an Excel-friendly format :-( .

I can't wait to fine tune my code, but I'll have to wait till tomorrow.

Re^2: Sorting dates with the Schwartzian Transform
by Wobbel (Acolyte) on Aug 15, 2011 at 13:19 UTC

I'm so close to the last step, but....

What if you sort on two or three special columns? In my case date 11 and time 12. Is your original code limited to one column, our is it possible to "map" on more then one time/date format?

I've Googled and tried a lot last week, but I'm stuck (on the syntaxis).

```my @sorted =
map \$_->[0],
sort { \$a->[11] cmp \$b->[11] || #Date, original
#      \$a->[12] cmp \$b->[12]    #Time, to do list
}
map [ \$_, join('', (/(..)-(..)-(....)/)[2,1,0]) ],
# map [ \$_, join('', (/(..):(..):(..)/)[2,1,0]) ], # Is it possible
+ to map two columns date and time?

@dates;  # DD-MM-YYYY
# HOURS:MIN:SEC

I've Googled and tried a lot last week, but I'm stuck (on the syntaxis).

I hope you understand my message despite the wording

Actually it seems more like you're stuck on syntax and arrays.

You need to read perlintro and Basic debugging checklist and How do I post a question effectively? and References quick reference

Also, when you have a program, with real, named variables, talking about columns can get confusing , talk about your variables instead ;)

The code you pasted will never have a 12 element array, nor do you want one.

I would go back to

```my @sorted =
map substr(\$_, 8),
sort
map join('', (/(..)-(..)-(....)/)[2,1,0], \$_),
@dates;  # DD-MM-YYYY
Don't get it? To understand, you would write a program like this
```#!/usr/bin/perl --
use strict;
use warnings;
use Data::Dumper;
my @dates = qw[
08-15-2011
08-10-2011
08-05-2011
];

print "\ndates ", Dumper( \@dates );

#~ my @firstTransform =  map join('', (/(..)-(..)-(....)/)[2,1,0], \$_)
+, @dates;  # DD-MM-YYYY
my @firstTransform =  map join('', ReorderForCmp(\$_), \$_), @dates;  #
+DD-MM-YYYY
print "\nfirstTransform ", Dumper( \@firstTransform  );

my @firstSorted = sort @firstTransform  ;
print "\nfirsSorted ", Dumper( \@firstSorted  );

my @finalTransform = map substr(\$_, 8), @firstSorted ;
print "\nfinalTransform ", Dumper( \@finalTransform );

sub ReorderForCmp {
my( \$one ) = @_;
my @date = \$one =~ /(..)-(..)-(....)/;

#~     return @date[2,1,0];
return \$date[2], \$date[1], \$date[0];
}

__END__
which produces this output
```dates \$VAR1 = [
'08-15-2011',
'08-10-2011',
'08-05-2011'
];

firstTransform \$VAR1 = [
'2011150808-15-2011',
'2011100808-10-2011',
'2011050808-05-2011'
];

'2011050808-05-2011',
'2011100808-10-2011',
'2011150808-15-2011'
];

finalTransform \$VAR1 = [
'08-05-2011',
'08-10-2011',
'08-15-2011'
];

So yes, it is possible to "map two columns date and time", just adjust sub ReorderForCmp to return iso-8601 style datetime ( YYYYMMDDHHMMSS)

I think it is time to make some excuses. I guess I'm a little bit desperate because of complete exhaustion. The last nine years I wrote a couple of Perlscripts and read/practised on a regular basis. Even our first two babyboys were no problem at all. But since eleven weeks, we got a lovely babygirl.

Sleep(10000); doesn't work for her....

If I look at my old code, It's easy to understand.

But a new improvent with only a half line of code...(OK, three lines. I'm not a pro)

I just don't see it anymore!

Thanks for your patience and the advice / links. I know them all and a few more.

Let me sleep for a week in a monastery or so and I will finish the last lines of code :-) .

Create A New User
Node Status?
node history
Node Type: note [id://918353]
help
Chatterbox?
and the sunlight beams...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2017-11-20 00:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In order to be able to say "I know Perl", you must have:

Results (282 votes). Check out past polls.

Notices?