什麼你想要做的是按數字排序。要做到這一點,您需要通過提供自己的方法來覆蓋默認的排序方法。此代碼:
my @sorted = sort @array;
真正含義:
my @sorted = sort { $a cmp $b } @array;
哪裏cmp
是逐一比較操作(排序按字母順序排列,或多或少)。你想使用<=>
,通常稱爲「太空船操作員」。
my @sorted = sort { $a <=> $b } @array;
但這種操作只能用數字來使用,一個字符串,如7-9
是不是一個真正的數字(儘管在這種情況下,它會工作,儘管發出警告Argument "7-9" isn't numeric in sort
)。
爲了克服這個警告和可能的錯誤,我們需要從我們想要排序的字符串中提取數字。我們用正則表達式匹配:/\d+/g
。這將匹配並返回字符串中的所有連續數字。
my @sorted = sort {
my ($a1, $a2) = $a =~ /\d+/g;
my ($b1, $b2) = $b =~ /\d+/g;
$a1 <=> $b1 || $a2 <=> $b2;
} @array;
我們捕獲並使用低和高範圍,最後我們執行兩個檢查。這意味着,在該$a1
和$b1
相等,<=>
返回0
,並且||
操作者的情況下執行所述替代比較,$a2 <=> $b2
。
在某些情況下,這種操作是昂貴的,這需要時間,並配有大型數據集,這將導致排序變得非常緩慢。在這種情況下,我們可以使用所謂的Schwartzian transform來緩存數據。在這種方法中,我們只需存儲正則表達式匹配的值並在排序時使用存儲的值。爲此,我們使用匿名數組ref [ ... ]
。最後,我們恢復原值,並丟棄緩存:
my @sorted = map { $_->[0] } # restore original
sort { $a->[1] <=> $b->[1] } # sort compares stored nums
map { [ $_, /\d+/g ] } # store original, and nums
@array;
如果你想要一個以上的水平排序,你只需要添加$a->[2] <=> $b->[2]
等。
來源
2014-11-23 13:51:49
TLP
'7-9'會在'7-11'之前嗎? – TLP 2014-11-23 13:36:12
顯示您嘗試過的代碼。你需要指定你自己的排序程序。 – TLP 2014-11-23 13:42:05
這不是必要的,在數據集中不可能發生這種情況,但是如果這樣做更容易,那就沒有問題了。 – Shikari 2014-11-23 13:42:33