【JavaScript】reduce()メソッドだけで配列を並べ替える方法
本記事では、数値の配列を受け取り、Array.prototype.sort()メソッドを使わずに並べ替えを行うJavaScript関数の実装方法を解説します。条件として、ソート処理にはArray.prototype.reduce()メソッドを使用します。
reduce()だけでソートする考え方
ポイントは、reduce()の累積値(アキュムレータ)を「すでにソート済みの配列」として扱うことです。元の配列から要素を1つずつ取り出し、そのたびにアキュムレータ内の適切な位置へ挿入していけば、最終的に完全にソートされた配列が完成します。これは古典的な挿入ソート(insertion sort)のアルゴリズムを、reduce()とsplice()で表現したものです。
サンプル配列
const arr = [4, 56, 5, 3, 34, 37, 89, 57, 98];
コード例
以下が実際のコードです。
// sort() メソッドを使わずに
// 従来型のループ構文も使わずに
// ES6 の reduce() だけで配列をソートします
const arr = [4, 56, 5, 3, 34, 37, 89, 57, 98];
const sortWithReduce = arr => {
return arr.reduce((acc, val) => {
let ind = 0;
// アキュムレータ内で val より小さい要素の後ろまで位置を進める
while (ind < acc.length && val > acc[ind]) {
ind++;
}
acc.splice(ind, 0, val);
return acc;
}, []);
};
console.log(sortWithReduce(arr));実行結果
コンソールには次のような出力が表示されます。
[ 3, 4, 5, 34, 37, 56, 57, 89, 98 ]
コードの解説
- 初期値の空配列 []:reduce()の第2引数に空配列を渡すことで、ソート結果を格納する新しい配列をアキュムレータとして用意しています。
- while文による位置探索:現在の要素valを挿入すべきインデックスを、アキュムレータの先頭から順に比較しながら求めます。
- splice()による挿入:求めた位置indにvalを挿入します。これにより、アキュムレータは毎回ソート済みの状態を保ちます。
なお、比較条件を「val > acc[ind]」から「val < acc[ind]」に変更すれば、降順(大きい順)のソートにも簡単に対応できます。このようにreduce()を活用すれば、sort()メソッドやfor文に頼らずとも、関数型的で宣言的なスタイルで配列の並べ替えを実装できます。
-
JavaScriptの配列findIndex()関数の使い方をわかりやすく解説
JavaScriptのfindIndex()関数は、配列の中から指定した条件を満たす最初の要素を見つけ、そのインデックス番号を返すメソッドです。条件に合う要素が見つかった場合、その要素のインデックスが返されます。もし条件を満たす要素がひとつも存在しない場合は、-1が返されるという特徴があります。findIndex()の基本的な使い方以下は、findIndex()関数を使ったサンプルコードです。ボタンをクリックすると、配列内の「lion」という要素のインデックスを取得して表示します。サンプルコード<!DOCTYPE html> <html lang="ja"
-
JavaScriptの配列some()メソッドの使い方をわかりやすく解説
JavaScriptのArray.some()メソッドは、配列の要素の中に、指定されたテスト(条件)を満たすものが「1つでも存在するかどうか」を判定するためのメソッドです。ここでいうテストとは、配列の各要素に対して順番に実行されるコールバック関数のことを指します。コールバック関数が1つでもtrueを返した時点でsome()はtrueを返し、すべての要素が条件を満たさなかった場合はfalseを返します。なお、空の配列に対して呼び出した場合は常にfalseを返すという仕様になっている点にも注意しましょう。some()メソッドのサンプルコード以下は、配列のsome()メソッドを使った具体的な実装例で