JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptで偶数を先頭に集めて昇順ソートする方法

正負の値や偶数・奇数が混在した数値の配列を扱う場面は少なくありません。本記事では、配列を昇順に並べ替えると同時に、偶数をすべて奇数より前に配置し、それぞれのグループ内でも昇順にソートする方法を解説します。

要件の整理

今回実現したいソートの条件は以下のとおりです。

  • 偶数はすべて奇数よりも先に配置する
  • 奇数はすべて偶数の後に配置する
  • 偶数同士・奇数同士は、それぞれ昇順に並べる

入力例と出力例

たとえば、次のような配列が入力されたケースを考えてみましょう。

const arr = [-2, 3, 6, -12, 9, 2, -4, -11, -8];

この場合、期待される出力は次のとおりです。

[ -12, -8, -4, -2, 2, 6, -11, 3, 9]

前半には偶数(-12、-8、-4、-2、2、6)が昇順で、後半には奇数(-11、3、9)が昇順で並んでいることが確認できます。

実装方法

Array.prototype.sort() メソッドにカスタム比較関数を渡すことで、この条件をシンプルに実現できます。比較関数の中では、まず各要素の偶奇を判定し、偶奇が異なる場合は偶数を優先、同じ場合は通常の数値比較で昇順に並べます。

サンプルコード

const arr = [-2, 3, 6, -12, 9, 2, -4, -11, -8];

const sorter = (a, b) => {
   const isAEven = !(a % 2);
   const isBEven = !(b % 2);
   if(isAEven && !isBEven){
      return -1;
   };
   if(!isAEven && isBEven){
      return 1;
   };
   return a - b;
};

arr.sort(sorter);
console.log(arr);

コードのポイント

  • !(a % 2):剰余演算子で偶数かどうかを判定しています。a % 2 が 0(偽値)になれば偶数なので、! で反転して true を返します。
  • return -1 / return 1:a が偶数で b が奇数なら a を手前に(-1)、その逆なら b を手前に(1)配置するよう指示します。
  • return a - b:両方が偶数、または両方が奇数の場合は差で比較し、昇順ソートを行います。

実行結果

コンソールに出力される結果は次のとおりです。

[
   -12, -8, -4, -2, 2,
   6, -11, 3, 9
]

補足:元の配列を保護したい場合

sort() は元の配列を直接変更する破壊的なメソッドです。元の配列を残しておきたい場合は、スプレッド構文を使ってコピーしてからソートすると安全です。

const sorted = [...arr].sort(sorter);

このひと工夫で、意図しないデータ書き換えを防ぎ、より堅牢なコードになります。

  1. JavaScriptの「厳密モード(Strict Mode)」とは?主な特徴と使い方を解説

    「厳密モード(Strict Mode)」は、ES5(ECMAScript 5)で導入された機能で、プログラム全体または個々の関数を「より厳格な」実行環境で動作させることができます。この厳密なコンテキストでは、一部の危険な操作や非推奨の構文が禁止され、エラーが発生した際には通常よりも詳細な例外がスローされます。その結果、開発者はバグの原因をより早く特定できるようになります。厳密モードの主な特徴は以下の通りです。厳密モードの主な特徴宣言されていない変数への代入がエラーになる:変数 foo が未宣言の状態で foo = bar; のように代入しようとすると、エラーが発生します。通常モードでは暗黙的に

  2. JavaScriptのwithステートメントとは?用途と使い方をわかりやすく解説

    JavaScriptのwithステートメントは、特定のプロパティに対してデフォルトのオブジェクトを指定し、冗長になりがちなオブジェクト参照の記述を省略するための構文です。withブロック内で指定したオブジェクトは、スコープチェーンの先頭に追加されるため、そのプロパティ名だけで直接アクセスできるようになります。 基本的な動作 通常、オブジェクトのプロパティにアクセスするには、毎回オブジェクト名を明示する必要があります。しかし、withステートメントを使えば、以下のようにコードを簡潔に書けます。 オブジェクト名の繰り返し記述を省略できる 同じオブジェクトの複数のプロパティへ短くアクセスできる 指