Sort numbers in xxxx format in perl

Say, for example, the numbers are in the format:

1.1.10 1.1.10.1 1.1.10.2 1.1.11 1.1.12 1.1.13 1.1.13.1 1.1.3 1.1.4 

And wat, which I am looking for output:

 1.1.3 1.1.4 1.1.10 1.1.10.1 1.1.10.2 1.1.11 1.1.12 1.1.13 1.1.13.1 
+6
source share
3 answers
 use Sort::Key::Natural qw( natsort ); my @sorted = natsort @data; 

or (without modules)

 my @sorted = map $_->[0], sort { $a->[1] cmp $b->[1] } map [ $_, pack('C*', split /\./) ], @data; 

or (without modules, faster, but input requires an array, not a list)

  my @sorted = map $data[unpack('N', $_)], sort map pack('NC*', $_, split /\./, $data[$_]), 0..$#data; 

In pack templates, you can change C to n or n . C allows numbers up to 255. n allows numbers up to 65535. n allows numbers up to 4 billion.

+11
source

Try the following:

 use Modern::Perl; use Sort::Naturally qw{nsort}; my @numbers = nsort(qw{1.1.10 1.1.10.1 1.1.10.2 1.1.11 1.1.12 1.1.13 1.1.13.1 1.1.3}); say for @numbers; 

Conclusion:

 1.1.3 1.1.10 1.1.10.1 1.1.10.2 1.1.11 1.1.12 1.1.13 1.1.13.1 

Hope this helps!

+4
source

It may be easier for you to understand:

 sub min { $_[0] <= $_[1] ? $_[0] : $_[1] } sub comp { ($a1,$a2) = @_; @a1 = @{$a1}; @a2 = @{$a2}; for (0..min(scalar @a1,scalar @a2)) { return 1 if $a1[$_] > $a2[$_]; return -1 if $a2[$_] > $a1[$_]; #exit early if an inequality is found } return 0 if @a1 == @a2; #both array are equal, thus both numbers are equal return @a1 > @a2 ? 1 : -1; #arrays are equal upto a certain point, thus longer array is 'greater' } @sourcearray = ('1.1.10','1.1.10.1','1.1.10.2','1.1.11','1.1.12','1.1.13','1.1.13.1','1.1.3','1.1.4'); @individual = map { [split /\./] } @sourcearray; #splits each number into arrays consisting of individual numbers @sorted = sort {comp($a,$b)} @individual; #sort algo decides which of these two arrays are 'greater' { local $" = "."; print "@{$sorted[$_]}\n" for 0..$#sorted; } 
0
source

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


All Articles