ファイル名順にソートする

Array#sortでファイル名順にソートするための比較関数。具体的には、数字部分は桁数に関わらず数字順に比較し、それ以外の文字は辞書順に比較する。全角数字にも対応。他にも考慮すべき点があるかもしれない。

function compareFileNames(a, b) {
  var fullWidthNums, i, j, A, B, aa, bb, fwn;
  fullWidthNums = '0123456789';
  i = j = -1;
  while (true) {
    A = a.charAt(++i).toLowerCase();
    B = b.charAt(++j).toLowerCase();
    if (!A) return -1;
    if (!B) return 1;
    if (~(fwn = fullWidthNums.indexOf(A))) A = ''+fwn;
    if (~(fwn = fullWidthNums.indexOf(B))) B = ''+fwn;
    if (isFinite(A) && isFinite(B)) {
      while ((aa = a.charAt(++i)) && isFinite(aa)
      || ~(fwn = fullWidthNums.indexOf(aa)) && (aa = ''+fwn)) A += aa;
      while ((bb = b.charAt(++j)) && isFinite(bb)
      || ~(fwn = fullWidthNums.indexOf(bb)) && (bb = ''+fwn)) B += bb;
      if (+A === +B) {
        if (A.length === B.length) continue;
        return B.length - A.length;
      } else {
        return +A - +B;
      }
    }
    if (A < B) return -1;
    if (A > B) return 1;
  }
  return 0;
}
var filenames = ['case9.txt', 'case11.txt', 'case8.txt', 'case10.txt'];

console.log(filenames.sort());
// ["case10.txt", "case11.txt", "case8.txt", "case9.txt"]

console.log(filenames.sort(compareFileNames));
// ["case8.txt", "case9.txt", "case10.txt", "case11.txt"]