Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

string array sorting issue in perl

Tags:

sorting

perl

I am running below code to sort strings and not getting the expected results.

Code:

use warnings;
use strict;

my @strArray= ("64.0.71","68.0.71","62.0.1","62.0.2","62.0.11");
my @sortedStrArray = sort { $a cmp $b } @strArray;

foreach my $element (@sortedStrArray ) {
    print "\n$element";
}

Result:

62.0.1
62.0.11   <--- these two
62.0.2    <---
64.0.71
68.0.71

Expected Result:

62.0.1
62.0.2    <---
62.0.11   <---
64.0.71
68.0.71
like image 564
user2083779 Avatar asked Apr 20 '26 01:04

user2083779


2 Answers

"1" character 0x31. "2" is character 0x32. 0x31 is less than 0x32, so "1" sorts before "2". Your expectations are incorrect.

To obtain the results you desire to obtain, you could use the following:

my @sortedStrArray =
   map substr($_, 3),
   sort
   map pack('CCCa*', split(/\./), $_),
   @strArray;

Or for a much wider range of inputs:

use Sort::Key::Natural qw( natsort );
my @sortedStrArray = natsort(@strArray);
like image 84
ikegami Avatar answered Apr 22 '26 19:04

ikegami


cmp is comparing lexicographically (like a dictionary), not numerically. This means it will go through your strings character by character until there is a mismatch. In the case of "62.0.11" vs. "62.0.2", the strings are equal up until "62.0." and then it finds a mismatch at the next character. Since 2 > 1, it sorts "62.0.2" > "62.0.11". I don't know what you are using your strings for or if you have any control over how they're formatted, but if you were to change the formatting to "62.00.02" (every segment has 2 digits) instead of "62.0.2" then they would be sorted as you expect.

like image 39
Lorkenpeist Avatar answered Apr 22 '26 18:04

Lorkenpeist



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!