Perl sort by length

Does anyone know how to sort a number by length?

Example: (11,111,122,12,2,13,21,15,211,22,213,2004)

I need a sorted array:

  eleven
 12
 13
 fifteen
 111
 122
 2
 21
 22
 213
 2004 
+4
source share
4 answers

It seems that the desired result indicates that you simply do not want to sort by the number of digits, but first sort by the first digit, and then by length.

The desired conclusion that you show omits 211 , so I will just put it where it belonged, in accordance with my understanding.

 #!/usr/bin/env perl use strict; use warnings; use Test::More; my @source = (11, 111, 122, 12, 2, 13, 21, 15, 211, 22, 213, 2004); my @desired = (11, 12, 13, 15, 111, 122, 2, 21, 22, 211, 213, 2004); my @sorted =sort { substr($a, 0, 1) <=> substr($b, 0, 1) || length($a) <=> length($b) || $a <=> $b # thanks @ikegami } @source; is_deeply(\@sorted, \@desired, 'Sorted and desired are the same'); 
+6
source
 my @sorted = sort { substr($a,0,1) <=> substr($b,0,1) || $a <=> $b } @unsorted; 

gives the order you requested. Or maybe you want

 my @sorted = sort { substr($a,0,1) <=> substr($b,0,1) || length($a) <=> length($b) || $a <=> $b } @unsorted; 

If 211 not skipped from the output you provided, I could tell you which one you want.

+2
source

Consider the so-called Schwartz transform , which avoids re-evaluating the sort keys by temporarily linking them to the input elements:

 my @sorted = map { $_->[0] } sort { $a->[1] cmp $b->[1] or $a->[0] <=> $b->[0] } map { [ $_ => sprintf "%.1s%08x", $_, length ] } @source; 
+2
source

This is provided by List::UtilsBy::sort_by

 use List::UtilsBy qw( sort_by ); my @sorted = sort_by { sprintf "%.1s%08x", $_, length } @source; 

This is the same as other Schwartzian Transform solutions proposed by others, but wrapped in a neat abstraction.

+1
source

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


All Articles