2011-11-11 20 views
0

私はperlのデフォルトの並べ替えが数値ではなくASCIIの並べ替えであることを理解しています。しかし、数値を持つ文字列をどのようにして並べ替えることができますか?例えば配列のperlハッシュ - 英数字キーの数値ソート?

、私は同様に、アレイのハッシュを有する:

myhash{ANN20021015_0101_XML_71.9} = ("anta", "hunna", "huma"); 
myhash{ANN20021115_0049_XML_14.1} = ("lqd", "qAl", "arrajul"); 
myhash{ANN20021115_0049_XML_14.2} = ("anna", "alwalada"); 

私はちょうどキーはソートはストリング内の数値であるsorted..butする必要があります。私は "1"に続く "10"で終わるので文字列ソートを行うことはできませんが、数値ソートもできません!

+3

おそらく便利です:http://perldoc.perl.org/functions/sort.html – sarnold

答えて

6

まず、あなたのコードは有効なPerlではなく、あなたが思う通りのことをしないかもしれません。常に

use strict; 
    use warnings; 

のいずれかの単純な間違いを解決します。コードは、全体の値以外の何かにソートするには

$myhash{'ANN20021015_0101_XML_71.9'} = ["anta", "hunna", "huma"]; 
    $myhash{'ANN20021115_0049_XML_14.1'} = ["lqd", "qAl", "arrajul"]; 
    $myhash{'ANN20021115_0049_XML_14.2'} = ["anna", "alwalada"]; 

のようになります、あなたはソートブロック内$a$bを変換し、その結果を数値<=>代わりの文字列的に<=>を並べ替えることができます。このコードは、

my @sorted = sort { 
    my ($aa) = $a =~ /.*_(.+)/; 
    my ($bb) = $b =~ /.*_(.+)/; 
    $aa <=> $bb; 
    } keys %myhash; 

を必要とする。しかし、あなたが大量のデータを持っている場合、あなたの文字列の数字の一部に彼らが

my @sorted = map { $_->[0] } 
       sort { $a->[1] cmp $b->[1] } 
       map { /.*_(.+)/ and [$_, $1] } 
       keys %myhash; 

を比較しているすべての時間を抽出避けるなる Schwartzian Transformを使用することが有益であるかもしれないものありません
0

あなたはカスタムソートを行う必要があります:あなたの文字列を部分にカットしますを認識し、必要に応じてそれらを比較します。

あなたの例では、あなたが望むように見えます。literaldigitsですが、あなたに合うように正規表現を変更することができます。

my $cut = qr/(.*?\.)(\d+)(.*)/; 
sort { 
    my @a = $a =~ $cut; my @b = $b =~ $cut; 
    $a[0] cmp $b[0] || $a[1] <=> $b[1] || $a[2] cmp $b[2] 
} keys %myhash; 

@ボロディンの答えもご覧ください。

関連する問題