Skip to content

Instantly share code, notes, and snippets.

@to
Last active January 2, 2018 15:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save to/b80c8ed4efa03c5dde905555a642ba06 to your computer and use it in GitHub Desktop.
Save to/b80c8ed4efa03c5dde905555a642ba06 to your computer and use it in GitHub Desktop.
Windowsのエクスプローラーの名前順ソートロジック
var expects = [
'!aa-a',
'_______z',
'___a',
'__a',
'_1',
'_a',
'_aa-a',
'1-a',
'a',
'a-',
'-a',
'--a',
'a_',
'a1',
'a2',
'a0003',
'a0003a',
'a003',
'a003a',
'a03',
'a03a',
'a3',
'a3a',
'a4',
'a20',
'aa',
'-aa',
'-aa-a',
'ab',
'pic 4',
'pic 5',
'pic4',
'pic05']
function logicalCompare(text1, text2) {
// 先頭と末尾のハイフンは取り除く
var tokens1 = text1.toLowerCase().replace(/^-+|-+$/, '').match(/([\d]+|.)/g);
var tokens2 = text2.toLowerCase().replace(/^-+|-+$/, '').match(/([\d]+|.)/g);
var token1, token2, num1, num2, type1, type2;
for (var i = 0, len = Math.min(tokens1.length, tokens2.length); i < len; ++i){
token1 = tokens1[i];
token2 = tokens2[i];
// 完全に同値の場合は次のトークンに移る
// (003 == 003など)
if(token1 == token2)
continue;
// 記号/数値/文字の順にタイプに分ける
// 空白などがあるためisNaNは使えない
if(/^\d/.test(token1)){
type1 = 2;
} else {
type1 = logicalCompare.smbols[token1]? 1 : 3;
}
if(/^\d/.test(token2)){
type2 = 2;
} else {
type2 = logicalCompare.smbols[token2]? 1 : 3;
}
// 同じタイプか?
if(type1 == type2){
// 数値同士の比較か?
if(type1 == 2){
// 数値に変換する
num1 = +token1;
num2 = +token2;
if(num1 != num2)
return (num1 < num2)? -1 : 1;
}
// 数値も文字列として比較する
// (003 < 03など)
return (token1 < token2)? -1 : 1;
}else{
return type1 - type2;
}
}
// 全てのトークンが同値だったか?
// (先頭と末尾のハイフンを除いて全体が合致)
if(tokens1.length == tokens2.length){
// 逆順で比較する
// (-a < a-などを反転する)
return (token1 > token2)? -1 : 1;
}
return tokens1.length - tokens2.length;
}
logicalCompare.smbols = {};
'_- !'.split('').forEach(function(c){
logicalCompare.smbols[c] = true;
});
@to
Copy link
Author

to commented Jan 2, 2018

DOSのdirコマンドで表示される名前順とも異なるみたいです…。
StrCmpLogicalW関数というのに処理が近いのか。
記号などの処理は適当で抜けがありそう。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment