The sort 配列プロトタイプで使用可能なメソッドを使用すると、配列の要素を並べ替えることができます。 これは、特定のニーズに合わせて並べ替えメカニズムを調整するために使用できるオプションのコールバック関数を受け入れます。

数値の配列については、数値の配列の並べ替えに関する以前の投稿を参照してください。

文字列の並べ替えは、 sort メソッドは機能します。

まず、 ECMAScript 標準では特定の並べ替えアルゴリズムが指定されておらず、すべてブラウザのベンダーによって異なります。

第二に、ケーシングは選別時に重要な役割を果たします。 並べ替えが機能するには、物事を順番に並べる必要があります。これは数字で取得できます。数字は当然順番に並んでいます(1、2、3、4…)。 文字列が比較されるとき、それらは同等の Unicode値に変換されます。これは当然のことながら数値であり、デフォルトでは昇順で順番に並べ替えられます。

文字のUnicode値

各文字のUnicode値(小文字または大文字)を取得するには、 charCodeAt 指定された文字インデックスの文字コードにアクセスするための文字列メソッド。

私と一緒にいて。

まず、文字だけでなく文字のユニコード値を取得するのに役立つユーティリティ関数を作成します。 参照しながら参照します。

// get Unicode values of character items in an array
function getCharactersUnicodeValue(characters) {
  const unicodeChart = new Map();
  characters.forEach(character => {
    unicodeChart.set(
      character,
      character.charCodeAt(character.indexOf(character))
    );
  });
  console.table(unicodeChart);
}

// get unicode values of a single character
function getCharacterUnicodeValue(character) {
  const value = character.charCodeAt(character.indexOf(character));
  console.log(value);
}

ここでマップが使用されていることに注意してください。


次のようなユーティリティ関数を呼び出します。

getCharactersUnicodeValue("ABCDEFabcdef".split("")); // array of characters: [ 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f' ]
// Result: {character → Unicode Value}
// { A → 65, B → 66, C → 67, D → 68, E → 69, F → 70, a → 97, b → 98, c → 99, d → 100, e → 101, f → 102 }

getCharacterUnicodeValue("A");
// Result: {character → Unicode Value}
// { A → 65 }

そして、ここにさらに別の例があります:

const crocodilian = "crOCoDiliaN".split(""); // array of characters i.e [ 'c', 'r', 'O', 'C', 'o', 'D', 'i', 'l', 'i', 'a', 'N' ]

getCharactersUnicodeValue(crocodilian);

// Result: {character → Unicode Value}
// { c → 99, r → 114, O → 79, C → 67, o → 111, D → 68, i → 105, l → 108, a → 97, N → 78 }

大文字文字が小文字文字の前に表示されることに注意してください。 そして、彼らは順番に来るでしょう。 これは次のように並べ替えられます。 ['Eggs', 'Tail', 'eggs']. どのように注意してください Tail 前に来る eggs? それは次の理由で予想されます:

getCharactersUnicodeValue(["Eggs", "Tail", "eggs"]);

// Result: {character → Unicode Value}
// { Eggs → 69, Tail → 84, eggs → 101 }
// 84 (T) of Tail comes numerically before 101 (e) of eggs

TL; DR :同じ大文字小文字(すべて上またはすべて下)でのみ文字列が形成される場合の並べ替えは簡単です。 課題は、混合ケースでのみ発生します。

大文字と小文字が混在する文字列の並べ替え

ほとんどの場合、ケーシングに関係なく、大文字と小文字が混在する文字列の配列を並べ替える必要があります。

const things = [ 'nest', 'Eggs', 'bite', 'gator', 'caYman', 'Grip', 'grips', 'Jaw', 'crocodilian', 'Bayou' ];

最終的には次のように並べ替える必要があります。

[ 'Bayou', 'bite', 'caYman', 'crocodilian', 'Eggs', 'gator', 'Grip', 'grips', 'Jaw', 'nest' ]

そしてそうではありません:

[ 'Bayou', 'Eggs', 'Grip', 'Jaw', 'bite', 'caYman', 'crocodilian', 'gator', 'grips', 'nest' ]

試行1:比較関数なし

比較関数なしでsortメソッドを呼び出すと、機能しません。

things.sort();

// ['Bayou', 'Eggs', 'Grip', 'Jaw', 'bite', 'caYman', 'crocodilian', 'gator', 'grips', 'nest']

試行2:比較関数を使用

function sortThings(a, b) {
  if (a > b) {
    return 1;
  } else if (a < b) {
    return -1;
  } else if (a === b) {
    return 0;
  }
}

次に、 comparison function:

things.sort(sortThings);

// [ 'Bayou', 'Eggs', 'Grip', 'Jaw', 'bite', 'caYman', 'crocodilian', 'gator', 'grips', 'nest' ]

それでも、それは機能しません。 実際、比較関数を作成していない方がよいでしょう。

試行3:比較関数と一般的なケースを使用

問題は、並べ替えで、things配列要素のデフォルトの混合ケースが引き続き使用されることです。必要なのは、ケースを一般的なケースに変換することです。lowercaseまたはUPPERCASEのいずれかで実行できます。

function sortThings(a, b) {
  a = a.toLowerCase();
  b = b.toLowerCase();

  if (a > b) {
    return 1;
  } else if (a < b) {
    return -1;
  } else if (a === b) {
    return 0;
  }
}

または、3値演算子を使用します。

function sortThings(a, b) {
  a = a.toLowerCase();
  b = b.toLowerCase();

  return a > b ? -1 : b > a ? 1 : 0;
}

次に、 comparison function:

things.sort(sortThings);

// ['Bayou', 'bite', 'caYman', 'crocodilian', 'Eggs', 'gator', 'Grip', 'grips', 'Jaw', 'nest' 'eggz']

そして、yippeeそれは今動作します!

しかし、待ってください、もっとあります

ブラウザベンダーには特定の並べ替えアルゴリズムがありますが、私たちが精通している必要のあるいくつかの手法があります。 並べ替えはで行われます charCodeAt(index) 基本。 2つの比較項目がほぼ類似しているシナリオでは、 charCodeAt(index) 継続的に比較されています。 インデックスが0から始まり、違いが生じるまで。

取った eggsEggz 例えば:

  1. 小文字に変換せずに、 Eggz 前に来る eggs のUnicode値が E → 69 その前に来る e → 101.

  2. 同様の大文字小文字(たとえば小文字)への変換がある場合、基本的に比較しています eggseggz. e → 101e → 101 は同じ。

ランニング:

['Eggz', 'eggs'].sort(sortThings);

// ['eggs', 'Eggz']

最後の文字で正しくソートします s → 115 and z → 122 決定論的なキャラクターであること。

チェックは次のように行われます。

  • [e→101]ggsと[e→101]ggz/ 101 === 101、次の文字に移動します
  • e[g→103]gsおよびe[g→103]gz/ 103 === 103、次の文字に移動します
  • eg[g→103]sおよびeg[g→103]z/ 103 === 103、次の文字に移動します
  • egg[s→115]とegg[z→122]/明らかに、115は122の前に来ます。

Etvoilà、それが決闘を決定します!

降順

降順で並べ替える必要がある場合は、次のように、比較関数のreturn1をreturn-1と交換するだけです。

function sortThings(a, b) {
  a = a.toLowerCase();
  b = b.toLowerCase();
  if (a > b) {
    return -1;
  } else if (b > a) {
    return 1;
  } else {
    return 0;
  }
}

または:

function sortThings(a, b) {
  a = a.toLowerCase();
  b = b.toLowerCase();
  return a > b ? -1 : b > a ? 1 : 0;
}

あるいは単に reverse ソートされた配列 reverse 配列メソッド。これは明らかに配列を逆の順序に逆にします。

things.sort(sortThings).reverse();

代替:localeCompareを使用する

localeCompare 文字列メソッドは、使用される大文字と小文字を区別せずに文字を比較できますが、文字列メソッドであるため、配列で直接使用することはできません。 私たちをソートするには things との配列 localeCompare 文字列メソッド、渡す localeCompare このような比較関数として:

things.sort((a, b) => a.localeCompare(b));

// [ 'Bayou', 'bite', 'caYman', 'crocodilian', 'Eggs', 'gator', 'Grip', 'grips', 'Jaw', 'nest' ]

一目でわかるコード

const things = [
  "nest",
  "Eggs",
  "bite",
  "gator",
  "caYman",
  "Grip",
  "grips",
  "Jaw",
  "crocodilian",
  "Bayou"
];
console.log(`unsorted: ${things.join(", ")}`);

function sortThings(a, b) {
  a = a.toLowerCase();
  b = b.toLowerCase();
  return a > b ? 1 : b > a ? -1 : 0;
}

console.log(`sorted:  ${things.sort(sortThings).join(", ")}`);

ソートを続けることを忘れないでください、世界はそれを必要としています。