Re: sort by a multiple columns
by Roy Johnson (Monsignor) on Sep 08, 2004 at 19:58 UTC
|
Here's a Schwartzian Transform solution (assuming your numbers don't exceed 12 digits):
print join "\n",
map { join ',', @{$_->[0]} }
sort { $a->[1] cmp $b->[1] }
map { my $x; for(@$_){$x.=sprintf("%012d",$_)}; [$_,$x] }
@un_sorted;
Caution: Contents may have been coded under pressure.
| [reply] [d/l] |
Re: sort by a multiple columns
by Roy Johnson (Monsignor) on Sep 08, 2004 at 19:07 UTC
|
print join "\n",
map { join ',', @$_ }
sort {
for (0..($#{$a}<$#{$b}?$#{$b}:$#{$a})) {
return $a->[$_] <=> $b->[$_] || $a->[$_] cmp $b->[$_] || next
}
} @un_sorted;
The mess on the for line determines how many elements there are in the longer of the two arrays being compared. The comparison is by number, then by string (so that null sorts before 0). If there's no difference either way, we continue through the loop. If there is a difference, it returns.
Update: I came up with a better way of handling different-length arrays below.
Caution: Contents may have been coded under pressure.
| [reply] [d/l] |
|
|
#! perl -slw
use strict;
my @un_sorted = ([3,4,23,4,5],[3,4,56,2,4],[2,3,43,5,3],[2,3,43,6],[3,
+4]);
print join "\n", map{ join ',', @$_ } sort {
for( 0 .. ( $#{$a} < $#{$b} ? $#{$b} : $#{$a} ) ) {
return ( $a->[$_] || 0 ) <=> ( $b->[$_] || 0 ) || next
}
} @un_sorted;
__END__
P:\test>before
Use of uninitialized value in numeric comparison (<=>) at P:\test\junk
+.pl line 10.
2,3,43,5,3
2,3,43,6
3,4
3,4,23,4,5
3,4,56,2,4
P:\test>after
2,3,43,5,3
2,3,43,6
3,4
3,4,23,4,5
3,4,56,2,4
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
| [reply] [d/l] |
|
|
I'm sorry, but neither you nor Roy Johnson follow the OP insofar as he would like undefined array elements to be treated like infinity rather than zero, that is, he says he wants
3,4,23,4,5
3,4,56,2,4
3,4
instead of
3,4
3,4,23,4,5
3,4,56,2,4
Might just have been a typo though, as it's quite unusual.
CombatSquirrel.
Entropy is the tendency of everything going to hell.
| [reply] [d/l] [select] |
|
|
|
|
|
|
| [reply] |
Re: sort by a multiple columns
by Pragma (Scribe) on Sep 08, 2004 at 21:58 UTC
|
Avoiding the Schwartzian:
my @sorted =
map [ map int, /.{12}/g ],
sort map { join '', map { sprintf "%012d", $_ } @$_ } @un_sorted;
| [reply] [d/l] |
Re: sort by a multiple columns
by BrowserUk (Patriarch) on Sep 08, 2004 at 22:19 UTC
|
#! perl -slw
use strict;
my @un_sorted = ([3,4,23,4,5],[3,4,56,2,4],[2,3,43,5,3],[2,3,43,6], [3
+,4] );
print join "\n", map{
join ',', @$_
} sort {
for( 0 .. ( $#{$a} < $#{$b} ? $#{$b} : $#{$a} ) ) {
return
( defined( $a->[ $_ ] ) ? $a->[ $_ ] : 1e308 )
<=>
( defined( $b->[ $_ ] ) ? $b->[ $_ ] : 1e308 )
|| next;
}
return 0;
} @un_sorted;
__END__
P:\test>junk
2,3,43,5,3
2,3,43,6
3,4,23,4,5
3,4,56,2,4
3,4
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
| [reply] [d/l] |
Re: sort by a multiple columns
by CombatSquirrel (Hermit) on Sep 08, 2004 at 22:03 UTC
|
This is really ugly (maybe someone could improve it with pack/unpack), but it reproduces your desired output:
#!perl
use strict;
use warnings;
my @un_sorted = (
[3, 4, 23, 4, 5],
[3, 4, 56, 2, 4],
[2, 3, 43, 5, 3],
[2, 3, 43, 6],
[3, 4]
);
my $end = chr(1e6);
print join "\n",
map { join ',', @$_ }
map { splice @$_, $#_; $_ }
map { [(map(ord, split('', $_)))]}
sort
map { join('', map chr, @$_) . $end }
@un_sorted;
It's a GRT (kinda, probably not the best performance, though). The trick with the end marker is especially ugly, but without it the output would be wrong.
Hope this helped.
CombatSquirrel.
Entropy is the tendency of everything going to hell.
| [reply] [d/l] |
Re: sort by a multiple columns
by dougX (Initiate) on Sep 08, 2004 at 22:57 UTC
|
my @arr4 = sort { $a->[0] cmp $b->[0] } @un_sorted;
print "Mutli-Dimensional Array\n";
for my $i ( 0 .. $#arr4) {
for my $j (0 .. $#{$arr4[$i]}) {
print "$arr4[$i][$j]\t";
}
print "\n";
}
Edited by Chady -- replade <pre> with <code> | [reply] [d/l] |
|
|
| [reply] |
Re: sort by a multiple columns
by mayhem (Hermit) on Sep 09, 2004 at 17:03 UTC
|
Simple and works for variety of elements, to the best of knowledge
my @un_sorted = ([3,4,23,4,5],[3,4,56,2,4],[2,3,43,5,3],[2,3,43,6],[3,
+4],[1,7,99,204],[1],[4,12],[110,99], [1111,19], [99]);
@un_sorted = sort { $a->[0] <=> $b->[0] } @un_sorted;
| [reply] [d/l] |