2

私の調査とグーグルによると、Javascript はロケール認識ソートと文字列比較をサポートしていないようです。はありますが、ブラウザ固有の違いlocaleCompare()と、使用するロケールを明示的に設定できないことが報告されています (OS ロケールが常に必要なロケールであるとは限りません)。ECMAScript 内に照合サポートを追加する意図がいくつかありますが、その前に、私たちは自分自身で行います。そして、結果がブラウザ間でどれだけ一貫しているかによって、私たちは永遠に独りでいるかもしれません:(.

私は次のコードを持っています。これは、アルファベット順の配列を作成します。速度を念頭に置いており、アイデアはhttps://stackoverflow.com/a/11598969/1691517から取得され、速度が向上しました。

この例では、words 配列には 13 のメンバーがあり、sort-function は 34 回呼び出されます。words-array の文字の一部を置き換えたいです (この質問のポイントではないため、どのような置き換えが行われるかを知る必要はありません)。これらの置換を sort-function ( で始まるものreturn function(a, b)) で行うと、配列メンバーごとに置換が複数回行われるため、コードは非効率的になります。もちろん、このクロージャーの外でこれらの置換を行うことができます。つまり、行の前words.sort(sortbyalphabet_timo);ですが、それは私が望むものではありません。

質問 1: "PREPARATION STARTS" 行と "PREPARATION ENDS" 行の間の words-array を変更して、並べ替え関数が変更された words-array を使用するようにすることは可能ですか?

質問 2: PREPARATION STARTS と PREPARATION ENDS の間のコードで使用できるように、クロージャーに引数を入力することは可能ですか? 私は成功せずにこれを試しました:

var caseinsensitive = true;
words.sort( sortbyalphabet_timo(caseinsensitive) );

最後にコード例を示します。すぐに実行できる例はhttp://jsfiddle.net/3E7wb/にあります。

var sortbyalphabet_timo = (function() {
  // PREPARATION STARTS
  var i, alphabet = "-0123456789AaÀàÁáÂâÃãÄäBbCcÇçDdEeÈèÉéÊêËëFfGgHhIiÌìÍíÎîÏïJjKkLlMmNnÑñOoÒòÓóÔôÕõÖöPpQqRrSsTtUuÙùÚúÛûÜüVvWwXxYyÝýŸÿZz",
  index = {};

  i = alphabet.length;
  while (i--) index[alphabet.charCodeAt(i)] = i;
  // PREPARATION ENDS

  return function(a, b) {
    var i, len, diff;

    if (typeof a === "string" && typeof b === "string") {
      (a.length > b.length) ? len = a.length : len = b.length;
      for (i = 0; i < len; i++) {
        diff = index[a.charCodeAt(i)] - index[b.charCodeAt(i)];

        if (diff !== 0) {
          return diff;
        }
      }
      // sort the shorter first
      return a.length - b.length;
    } else {
      return 0;
    }
  };
})();

var words = ['tauschen', '66', '55', '33', 'täuschen', 'andern', 'ändern', 'Ast', 'Äste', 'dosen', 'dösen', 'Donaudam-0', 'Donaudam-1'];
$('#orig').html(words.toString());
words.sort(sortbyalphabet_timo);
$('#sorted').html(words.toString());`
4

1 に答える 1

2

ソート機能が変更されたwords-arrayを使用するように、「PREPARATION STARTS」と「PREPARATION ENDS」の行の間のwords-arrayを変更することは可能ですか?

いいえ、そうではありません。.sort配列自体にアクセスすることはできません。関数は、後で配列で呼び出されたときに使用される比較関数のみを構築します。配列を変更する必要がある場合は、配列を引数として取得する関数を作成する必要があります。たとえば、 にメソッドを追加できますArray.prototype。次のようになります

function mysort(arr) {
    // Preparation
    // declaration of compare function
    // OR execution of closure to get the compare function
    arr.sort(comparefn);
    return arr;
}

PREPARATION STARTS と PREPARATION ENDS の間のコードがそれらを使用できるように、クロージャーに引数を入力することは可能ですか?

sortbyalphabet_timo(caseinsensitive)はい、もちろん - それがクロージャーを使用する理由です:-) ただし、現在のコードでは使用できません。クロージャーはすぐに呼び出され (IIFE と呼ばれます)、比較関数を返します。これをデモのように sort に渡します。

sortbyalphabet_timo結果ではなくクロージャーになりたい場合は、その後の括弧を削除する必要があります。また、クロージャ スコープ全体 (comparefunction を含む) でアクセス可能な引数を使用することもできます。

var sortbyalphabet_timo_closure = function(caseinsensitive) {
    // Preparation, potentially using the arguments
    // Declaration of compare function, potentially using the arguments
    return comparefn;
}
// then use
words.sort(sortbyalphabet_timo_closure(true));

現在、これを行っています:

var sortbyalphabet_timo_closure = function(/*having no arguments*/) {
    // Preparation, potentially using the arguments
    // Declaration of compare function, potentially using the arguments
    return comparefn;
}
var sortbyalphabet_timo = sortbyalphabet_timo_closure();
// then use
words.sort(sortbyalphabet_timo);

…複数回ソートする必要がある場合は、クロージャの実行結果をキャッシュするだけです。

于 2012-09-26T19:34:51.297 に答える