3

我在下面运行代码来对字符串进行排序,但没有得到预期的结果。

代码:

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";
}

结果:

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

预期结果:

62.0.1
62.0.2    <---
62.0.11   <---
64.0.71
68.0.71
4

4 回答 4

9

“1”字符 0x31。“2”是字符 0x32。0x31 小于 0x32,因此“1”排在“2”之前。你的期望是不正确的。

要获得您希望获得的结果,您可以使用以下内容:

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

或者对于更广泛的输入:

use Sort::Key::Natural qw( natsort );
my @sortedStrArray = natsort(@strArray);
于 2013-03-01T18:41:37.913 回答
1

cmp 是按字典顺序比较(如字典),而不是按数字比较。这意味着它将逐个字符地遍历您的字符串,直到出现不匹配。在“62.0.11”与“62.0.2”的情况下,字符串在“62.0”之前是相等的。然后它在下一个字符处发现不匹配。由于 2 > 1,它排序“62.0.2”>“62.0.11”。我不知道您使用字符串的目的是什么,或者您是否可以控制它们的格式,但如果您要将格式更改为“62.00.02”(每个段有 2 位数字)而不是“62.0 .2" 那么它们将按照您的预期进行排序。

于 2013-03-01T18:51:21.707 回答
0

试试 Perl 模块Sort::Versions,它旨在为您提供您所期望的。

http://metacpan.org/pod/Sort::Versions

它也支持字母数字版本 ID。

于 2013-03-01T18:49:43.440 回答
0

Schwartzian_transform

这是randal schwartz transofm的用法:

首先,了解您想要什么:
按第一个数字排序,然后是第二个,然后是第三个:

让我们这样做:

use warnings;
use strict;
use Data::Dumper;
my @strArray= ("64.0.71","68.0.71","62.0.1","62.0.2","62.0.11");
my @transformedArray = map{[$_,(split(/\./,$_))]}@strArray;

=pod
  here @transformedArray have such structure: 
  $each_element_of_array: [$element_from_original_array, $firstNumber, $secondNumber, $thirdNumber];
  for example:
  $transformedArray[0] ==== ["64.0.71", 64, 0, 71];
  after that we will sort it 
  first by first number
  then: by second number
  then: by third number
=cut

my @sortedArray =  map{$_->[0]} # save only your original string.
                  sort{$a->[3]<=>$b->[3]}
                  sort{$a->[2]<=>$b->[2]}
                  sort{$a->[1]<=>$b->[1]} 
                                         @transformedArray;
print Dumper(\@sortedArray);
于 2013-03-01T19:13:07.987 回答