グリッド、レポート、ドロップダウンボックスなどでユーザーにデータを表示しているとします。問題のデータには、請求書番号というフィールドが含まれています。このフィールドには、2/3の時間の数値のみが含まれますが、残りの1/3の時間は、英数字の混合です。
このため、並べ替えアルゴリズムでは、アルファを数値ではなく数値で並べ替えます。 。このため、1000は99よりはるかに前になります。最初の桁がソートされているため、値全体ではありません。 000333のような他のアイテムは「333」として扱われず、222より前に表示されます。
ここに標準はありますか?すべての値を数値に変換して、別の方法で並べ替える必要がありますか?それらはどのように統合されますか?または、英数字による並べ替えが正しい方法ですか?
コメント
- 言うことができる場合は、部分文字列を使用して最初の3つを切り捨てます。アルファベットを持ち、最後の3桁のみに基づいてソートされる数字、たとえばABC333および000222-これを実装できます。確かに、表示中は000222、ABC333の順になります。ただし、視覚的には、いくつかの数字に対してゼロを表示し、他の数字に対してアルファベットを表示するのは少し混乱します。アルファベットは何を示唆していますか?
- SubStringがないように、長さが異なります。 " 10 "が" 9 (実際には9より前のFAR)は、アルファ数値を頻繁に使用しない'ユーザーを混乱させるでしょう。一方、これらの純粋な混合物は、実際には'私が見ることができるような良い方法で並べ替えることはできません。
- これらが請求書である場合、並べ替えることができますか?日付別ですか、それとも請求書番号自体に従って明示的に並べ替える必要がありますか?たぶん、テーブルから別の列を使用して、それに応じて並べ替えることができます。これらが昇順で生成されると仮定すると、請求書の時系列順で、最も頻繁に生成されるものが一番上に表示されます。ドロップダウンが実際に何のためにあるのか、またはユーザーがソートからどのように利益を得ることができるのかわかりません。フィールドの使用法についてもっと教えていただければ、もっと役に立ちます!
- 'はユーザー次第です。レポート、Net 30に対する残高を確認できる会計画面(1つのベンダーからのすべての請求書を参照)などを介してこのデータを表示できます。ユーザーは、画面またはレポートの並べ替え方法を選択します。日付はオプションです。しかし、請求書番号もそうです。これらは私のアプリケーションによって生成されません。サプライ品や部品などをベンダーに注文します。その特定のベンダーが請求書番号をあなたにキックバックします。 5つのオンラインストアから注文し、5つの注文番号を取得した場合のように。数値のものもあればそうでないものもあります。
- これらの数値を数値形式に変換する必要があります。これは、英数字の値を並べ替える場合にのみ使用してください。さらに混乱を招くために、変換された数値をユーザーに表示する必要はありません。ただし、たとえば、アルファベットを補完する日付という別の列を作成することを強くお勧めします。アルファベットの並べ替えは少し混乱するため、ユーザーが関連する日付などを把握するのに役立つ別の列が大いに役立ちます。
回答
Windows 7以降、Microsoftは、ファイル名でディレクトリを並べ替えるデフォルトの方法を「数値」並べ替えを使用するように変更しました。 (いくつかの情報ここ)
その動作の仕様を見つけることができませんでしたが、なんとかリバースエンジニアリングできました。このアルゴリズムは2つの英数字の文字列を比較し、どちらが先かを判断します。
-
各ファイル名をアルファベットと数字の部分に分割します。つまり、名前
text123moretext456
がリスト{"text"
、"123"
、"moretext"
、"456"
} -
2つの分割名の各部分について、次の比較を実行します。
- 両方の部分が厳密に数値である場合は、比較します。それらを数字として
- 数字が同じ場合は、文字列として比較します
- 文字列が同じ場合は、次の部分に進みます
- 両方の部分が厳密に文字である場合は、文字列として比較します
- 同じである場合は、次の部分に進みます
- 両方の部分が厳密に数値である場合は、比較します。それらを数字として
- パーツが足りなくなった場合、パーツが最も少ない名前がfになります。最初の
次のような順序になります。
2 12 200000 1000000 a a12 b2 text2 text2a text2a2 text2a12 text2b text12 text12a
コメント
- これはまさに私が探していたものであり、結果のソート順は理にかなっています。ありがとうございます!
回答
この質問(特に@Harrison Paineの回答)は私を助けてくれました私のプロジェクトと私は、将来の参考のために彼の答えの[javascript]実装を提供したいと思います。並べ替えは次のとおりですfunction
:
var win7sort = function(a, b) { var regex = /[^\d]+|\d+/g; // Split each filename into alphabetical and numeric parts var ar = a.match(regex); var br = b.match(regex); var localeCompare; // For each part in the two split names, perform the following comparison: for(var ia in ar) { for(var ib in br) { var ari = ar[ib]; if(ari == undefined) { ari = ""; } var bri = br[ib]; if(bri == undefined) { bri = ""; } // If both parts are strictly numeric, compare them as numbers if(!isNaN(ari) && !isNaN(bri)) { localeCompare = ari.localeCompare(bri, {}, { numeric: true }); } else { localeCompare = ari.localeCompare(bri, {}, { ignorePunctuation: true, sensitivity: "base" }); } if(localeCompare != 0) { // If you run out of parts, the name with the fewest parts comes first return localeCompare; } // If they"re the same, move on to the next part } } return localeCompare; };
使用方法は次のとおりです:
var list = ["1", "a", "z", "new folder 2", "new folder 03", "new folder 03-a", "new folder 039", "new folder 5", "new folder 41", "2", "21", "3", "41", "100"]; var sortedList = list.sort(win7sort);