I have this array:
@raw_stack = (
'900244~dfasdf~ddd3',
'900122~dfasdf~ddd1',
'900244~dfasdf~ddd2',
'900456~dfasdf~ddd4',
'900312~dfasdf~ddd3',
'900456~dfasdf~ddd5',
);
I'd like to sort it by the first '~' element. Is there a more elegant way to solve this rather than looping and splitting through each value?
Use Schwartzian transform:
my @raw_stack = (
'900244~dfasdf~ddd3',
'900122~dfasdf~ddd1',
'900244~dfasdf~ddd2',
'900456~dfasdf~ddd4',
'900312~dfasdf~ddd3',
'900456~dfasdf~ddd5',
);
my @sorted =
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [$_, (split/~/)[0]] } @raw_stack;
dump@sorted;
Benchmark:
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
use Benchmark qw(:all);
my $s = '~dfasdf~ddd3';
my @arr = ();
for(0..20000) {
push @arr, int(rand(100000)) . $s;
}
my $count = -3;
cmpthese($count, {
'ST' => sub {
my @sorted =
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [$_, (split/~/)[0]] } @arr;
},
'SORT' => sub {
my @sorted =
sort {
my ($a_0) = split /~/, $a;
my ($b_0) = split /~/, $b;
$a_0 <=> $b_0
} @arr;
},
});
result:
array of 200 elements:
Rate SORT ST
SORT 267/s -- -61%
ST 689/s 158% --
array of 2000 elements:
Rate SORT ST
SORT 18.0/s -- -71%
ST 61.5/s 242% --
array of 20000 elements:
Rate SORT ST
SORT 1.35/s -- -73%
ST 4.96/s 266% --
Sort and list slices?
sort { ( split( /~/, $a ) )[0] <=> ( split( /~/, $b ) )[0] } @raw_stack;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With