Home > Archive > PERL Miscellaneous > June 2007 > sort function, in non-standard cases
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
sort function, in non-standard cases
|
|
| alexxx.magni@gmail.com 2007-06-26, 8:03 am |
| Hi everybody,
I need some hints on how to setup the sort function in a couple of
cases that happened to me recently
<disclaimer>I already did perldoc -f sort, yet I found mainly
discussed numerical/alphabetical cases</disclaimer>
The two sort problems I had - neither of which I was able to solve -
are the following:
1) given in @a a list of files/directories (e.g. returned by
File::Find), sort it directories first, then symlinks, then common
files.
The nearer I came was:
@a=sort {my $x= -d $a; my $y= -d $b; return $x
<=> $y} @a;
but it doesnt work.
2) sort @a, based on the existence/non-existence of the hash value
$c{$a}, where $a's are the elements of @a.
Both the problems are related to my difficulty of translating them in
some kind of comparison between two generic elements $a vs $b, as in
the typical $a<=>$b
Any hint is welcome!
Alessandro Magni
| |
| Joe Smith 2007-06-26, 8:03 am |
| alexxx.magni@gmail.com wrote:
> Hi everybody,
> I need some hints on how to setup the sort function in a couple of
> cases that happened to me recently
>
> <disclaimer>I already did perldoc -f sort, yet I found mainly
> discussed numerical/alphabetical cases</disclaimer>
It is unfortunate that `perldoc -f sort` does not mention "Schwartzian Transform".
http://en.wikipedia.org/wiki/Schwartzian_transform
> sort it directories first, then symlinks, then common files.
#!/usr/bin/perl
# Purpose: Outputs directory listing, dirs first, then symlinks, then rest
use strict; use warnings;
push @ARGV,(glob '*') unless @ARGV;
my @typed_names =
map {substr $_,1}
sort
map { -l $_ ? "l$_" : -d $_ ? "d$_" : "r$_"}
@ARGV;
print join("\n",@typed_names),"\n";
-Joe
| |
| John W. Krahn 2007-06-26, 10:03 pm |
| Joe Smith wrote:
> alexxx.magni@gmail.com wrote:
>
> #!/usr/bin/perl
> # Purpose: Outputs directory listing, dirs first, then symlinks, then rest
> use strict; use warnings;
>
> push @ARGV,(glob '*') unless @ARGV;
> my @typed_names =
> map {substr $_,1}
> sort
> map { -l $_ ? "l$_" : -d $_ ? "d$_" : "r$_"}
> @ARGV;
> print join("\n",@typed_names),"\n";
You only need to stat the files once:
my @typed_names =
map {substr $_,1}
sort
map { -l $_ ? "l$_" : -d _ ? "d$_" : "r$_"}
@ARGV;
John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
| |
| John W. Krahn 2007-06-26, 10:03 pm |
| anno4000@radom.zrz.tu-berlin.de wrote:
>
> That is a typical candidate for a Schwartz transform. To each file,
> assign a rank of 0, 1, or 2 according as it is a directory, a symlink
> or anything else. Then sort according to rank, breaking ties by
> comparing the file names:
>
> my @sorted_files = map $_->[ 0] =>
> sort { $a->[ 1] <=> $b->[ 1] || $a->[ 0] cmp $b->[ 0] }
> map {
> my $rank = 2;
> $rank = 0 if -d;
> $rank = 1 if -l;
> [ $_, $rank];
> }
> @files;
You only need to stat the files once:
my @sorted_files = map $_->[ 0] =>
sort { $a->[ 1] <=> $b->[ 1] || $a->[ 0] cmp $b->[ 0] }
map {
my $rank = 2;
$rank = 0 if -d;
$rank = 1 if -l _;
[ $_, $rank];
}
@files;
John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
| |
| John W. Krahn 2007-06-26, 10:03 pm |
| anno4000@radom.zrz.tu-berlin.de wrote:
>
> That's not strictly a Schwartz transform
"Schwartzian Transform"
> but a Guttman-Roesler transform (GRT).
That should be Guttman-Rosler.
http://www.sysarch.com/Perl/sort_paper.html
John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
|
|
|
|
|