print map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [ $_, (split /\|/)[3] ] }
@lines;
But how would I use this paradigm if there was a more
complicated key? For example, in my original example, if I
needed to sort by the second column, which contains a date, I
would have done something like:
@fields = split(/\|/);
($dy,$mn,$yr) = split(/\//,$field[1]);
push @key, "$yr$mn$dy";
etc...
How would this transform approach allow me to do something similar?
Well, obviously, it's going to be a little messier, but the concept is
the same;
print map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [
$_,
do {
my ($d,$m,$y) = split '/', (split /\|/)[1];
"$y$m$d";
}
]
}
@lines;
When trying to decipher a Schwartzian transform, read it backwards.
1) We start with the array of @lines.
2) The bottom map transform the array of lines into a list of array
references. The first element of the array reference is the line
itself, and the second is the value we want to sort by eventually. In
this case, that's the "year-month-day" value.
3) The sort now takes this list of array references, and sorts it by
the second element of each referenced array. That is, it sorts the
array references on our sort key.
4) The top map takes this sorted list of array references and
transforms it to a new list containing the first element of each
referenced array - that is, the original line.
5) print is passed this list of lines.
It might be helpful if you break it out into it's individual steps.
In this case, I'll use a generic get_key() to represent obtaining the
sort key from your line. That's the only part of a Schwartzian
transform that ever changes. The syntax is always the same for the
rest of it.
my @lines_keys = map { [ $_, get_key($_) ] } @lines;
my @sorted_lines_keys = sort { $a->[1] cmp $b->[1] } @lines_keys;
my @sorted_lines = map { $_->[0] } @sorted_lines_keys;
print @sorted_lines;
Hope that helps,
Paul Lalli