1

PerlのデフォルトのソートはASCIIソートであり、数値ではないことを理解しています。しかし、どうすれば数字のある文字列を数値で並べ替えることができますか?

たとえば、次のような配列のハッシュがあります。

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

キーを並べ替える必要があります...しかし、並べ替えは文字列内で数値です。「1」の後に「10」が続くため、文字列の並べ替えはできませんが、数値の並べ替えもできません。

4

2 に答える 2

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とを変換し、結果を stringwise ではなく数値で並べ替えることができます。このコードは必要なことを行います$b<=><=>

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

ただし、大量のデータがある場合は、比較するたびに文字列の数値部分を抽出することを回避するSchwartzian Transformを使用すると有益な場合があります。

  my @sorted = map  { $_->[0] }
               sort { $a->[1] cmp $b->[1] }
               map  { /.*_(.+)/ and [$_, $1] }
               keys %myhash;
于 2011-11-11T10:54:02.627 に答える
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;

ボロディンの答えも参照してください。

于 2011-11-11T11:05:49.020 に答える