
Kenosis
User
Mar 1, 2013, 7:34 PM
Post #4 of 6
(161 views)
|
|
Re: [lilmark] sorting by element of an array within a hash
[In reply to]
|
Can't Post
|
|
It appears that you're attempting to sort your records based upon the value of PERCT1. A Schwartzian Transform (ST) is the canonical way of sorting records based upon a column's values. However, if each of your records is uniquely identified (and it appears that, at least, Group_n may do this), then you can use a hash where the key is the record, the value is that record's PERCT1, and you sort the hash by value:
use strict; use warnings; my %hash; do{chomp; $hash{$_} = (split)[2]} for <DATA>; print "$_\n" for sort { $hash{$b} <=> $hash{$a} } keys %hash; __DATA__ 201302 GROUP_1 0.44 201 6,000 0.91 201302 GROUP_2 0.42 192 10,806 1.65 201302 GROUP_3 0.38 159 4,065 0.62 201303 GROUP_11 0.15 -474 4,691 0.58 201303 GROUP_15 0.08 -209 3,010 0.37 201303 GROUP_13 0.05 -93 9,879 1.22 201304 GROUP_12 0.04 184 10,977 2.13 201304 GROUP_4 0.00 91 9,184 1.78 201304 GROUP_5 -0.01 87 14,042 2.72 201305 GROUP_15 0.35 47 3,667 0.71 201305 GROUP_10 0.34 44 8,961 1.74 201305 GROUP_7 0.30 26 8,130 1.58 Output:
201302 GROUP_1 0.44 201 6,000 0.91 201302 GROUP_2 0.42 192 10,806 1.65 201302 GROUP_3 0.38 159 4,065 0.62 201305 GROUP_15 0.35 47 3,667 0.71 201305 GROUP_10 0.34 44 8,961 1.74 201305 GROUP_7 0.30 26 8,130 1.58 201303 GROUP_11 0.15 -474 4,691 0.58 201303 GROUP_15 0.08 -209 3,010 0.37 201303 GROUP_13 0.05 -93 9,879 1.22 201304 GROUP_12 0.04 184 10,977 2.13 201304 GROUP_4 0.00 91 9,184 1.78 201304 GROUP_5 -0.01 87 14,042 2.72 However, if it's possible for two keys to be the same, use the ST:
print map "$_->[0]\n", sort { $b->[1] <=> $a->[1] } map {chomp; [ $_, (split)[2] ] } <DATA>; To my eyes, the code for sorting by value appears simpler, and it benchmarks modestly faster than the ST on your small data set:
use strict; use warnings; use Benchmark qw(cmpthese); chomp ( my @data = <DATA> ); # Schwartzian Transform sub stSort { my @sorted = map $_->[0], sort { $b->[1] <=> $a->[1] } map { [ $_, (split)[2] ] } @data; } # Sort by hash value sub valSort { my %hash; $hash{$_} = (split)[2] for @data; my @sorted = sort { $hash{$b} <=> $hash{$a} } keys %hash; } cmpthese( -5, { stSort => sub { stSort() }, valSort => sub { valSort() } } ); __DATA__ 201302 GROUP_1 0.44 201 6,000 0.91 201302 GROUP_2 0.42 192 10,806 1.65 201302 GROUP_3 0.38 159 4,065 0.62 201303 GROUP_11 0.15 -474 4,691 0.58 201303 GROUP_15 0.08 -209 3,010 0.37 201303 GROUP_13 0.05 -93 9,879 1.22 201304 GROUP_12 0.04 184 10,977 2.13 201304 GROUP_4 0.00 91 9,184 1.78 201304 GROUP_5 -0.01 87 14,042 2.72 201305 GROUP_15 0.35 47 3,667 0.71 201305 GROUP_10 0.34 44 8,961 1.74 201305 GROUP_7 0.30 26 8,130 1.58 Results:
Rate stSort valSort Rate stSort valSort stSort 47282/s -- -12% valSort 54007/s 14% --
|