いくつかのファイルを注文するためにPerlでTcl辞書ソートを実装しようとしています。 Tclのを知らない人のために、あなたはそれが彼らの値で連続整数をソートするために取得することができ、ここで詳述だ:Odd Perl '辞書'ソートの振る舞い
http://www.perlmonks.org/index.pl?node_id=160157
を要約すると: の与えられた配列:
qw(
bigbang
x10y
x9y
bigboy
bigBoy
x11y
)
を大文字と小文字を区別しない文字でソートされます。その後、タイブレイカーとして大文字と小文字が区別されます。その後は数字で区切られ、ソートでは単一の数字として解釈されます。
.の前に現れるため、1にx10yとx11y上に表示されるx9yで
、標準のASCIIソートで、x10yとx11yがx9yの上に来るとしながら、私は関数としてそのリンクにJuerdの例を実装しようとしましたが、私の場合、私は以下のように、バージョン番号のリストを持っているソート完全に模倣したTcl辞書ソート:
qw{ 1 1.0 1.01 1.2 1.02 1.0003 1.102 1.103 1.203 102a 102b 103a 103b 123 };
しかし、絶対パスをファイルに使用されている場合、順序は台無し。
以下にサンプルスクリプトを掲載しました。なぜ機能がうまくいかないのか誰にでも分かるか、もっと近代的な選択肢を提案できれば(10年前に私が書いた例:P)、私はそれを感謝します。
そして、あなたがアクションでTclの辞書の並べ替えを見たい場合は、下のリンクをチェック:事前に
感謝を!
編集: -私は解決策を導いてくれたchoroba
のおかげで!機能は次のとおりです。
sub dict_sort {
my @unsorted = @_;
my @sorted =
map $_->[0],
sort {
my $i = 0;
{
my $A = $a->[1][$i];
my $B = $b->[1][$i];
defined($A) || defined($B) # Stop if both undef
and (
defined($A) <=> defined($B) # Defined wins over undef
or (
$A !~ /\d/ || $B !~ /\d/ # $A or $B is non-integer
? (lc $A cmp lc $B) # ?? Stringy lowercase
|| ( $A cmp $B) # -> Tie breaker
: $A <=> $B # :: $A and $B are integers
or (
length($A) <=> length($B) # If numeric comparison returns the same, check length to sort by leading zeroes
)
)
or ++$i && redo # tie => next part
);
}
}
map [ $_, [ split /(\d+)/ ] ], @unsorted;
return @sorted;
}
明確にするために、Tclの辞書ソートは、各単語を唯一の数字と非数字の交互の文字列に分割します。数字シーケンスは数値でソートされます(2つの値が同じ場合、先頭のゼロを処理するために少し魔法を使います)。また、非数字シーケンスは大文字と小文字を区別しないASCIIとしてソートされます。数字で始まるキーと非数字で始まるキーを比較すると、先頭の数字が最初に来ます。 –
誰かが尋ねる前に、これは、ファイル名がどのように分類されるべきなのか、ユーザーが見ているような気がしています。 –
Hm、先行ゼロがここで問題を引き起こしている可能性がありますが、バージョン文字列と絶対パスの両方で同じエラーが発生することはありません。 – Rohaq