Best way to sort an array with an unusual value

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 would like to sort it by the first element of "~". Is there a more elegant way to solve this, rather than looping and breaking each value?

+4
source share
4 answers

Sort and list of fragments?

 sort { ( split( /~/, $a ) )[0] <=> ( split( /~/, $b ) )[0] } @raw_stack; 
+4
source

Use the Schwartz 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:

an array of 200 elements:

  Rate SORT ST SORT 267/s -- -61% ST 689/s 158% -- 

an array of 2000 elements:

  Rate SORT ST SORT 18.0/s -- -71% ST 61.5/s 242% -- 

an array of 20,000 elements:

  Rate SORT ST SORT 1.35/s -- -73% ST 4.96/s 266% -- 
+5
source

This can help. They show you how to extract parts of strings to use to sort large strings:

+2
source

Is it always 6 digits? If so, it would be the simplest and fastest:

 my @sorted_stack = sort @raw_stack; 

If not,

 my @sorted_stack = sort { my ($a_0) = split /~/, $a; my ($b_0) = split /~/, $b; $a_0 <=> $b_0 } @raw_stack; 

The Schwartz transformation may be cleaner if you get used to it, but in this case it is slower: [ Update : Apparently, this is actually faster than my second solution for large lists. It’s never faster than the first, though]

 my @sorted_stack = map $_->[0], sort { $a->[1] <=> $b->[1] } map [ $_, split /~/ ], @raw_stack; 
+1
source

Source: https://habr.com/ru/post/1398848/


All Articles