何をしたいユーティリティか:「順序反転」
「順序反転」は、配列の要素の並びを逆向きにする処理です。[1, 2, 3] を [3, 2, 1] にする、というイメージですね。
業務だと、例えばこういう場面で使います。
ログを「新しい順」に並べ替えたい。
履歴リストを「最近のものから」表示したい。
ソート済み配列を逆順で扱いたい。
JavaScript には標準で Array.prototype.reverse がありますが、「破壊的(元の配列を書き換える)」というクセがあるので、ユーティリティとしてきちんと扱い方を決めておくと安全です。
基本:標準の reverse と非破壊版 reverseArray
標準の reverse の動き
まずは素の reverse を確認しておきます。
const arr = [1, 2, 3];
const reversed = arr.reverse();
console.log(arr); // [3, 2, 1]
console.log(reversed); // [3, 2, 1]
JavaScriptここが重要ポイントです。
reverseは「元の配列そのもの」を書き換える- 戻り値も同じ配列への参照なので、
arrとreversedは同じもの
業務コードでこれをうっかり使うと、「どこかで順序が勝手に変わっている」ようなバグにつながりやすいです。
非破壊版の順序反転ユーティリティ
そこで、「元の配列は変えずに、逆順の新しい配列を返す」ユーティリティを用意します。
function reverseArray(array) {
if (!Array.isArray(array)) {
return [];
}
return array.slice().reverse();
}
JavaScriptここでやっていることをかみ砕きます。
Array.isArrayで配列かどうかをチェックし、違ったら空配列を返すslice()で配列のコピーを作る- コピーに対して
reverse()を呼ぶことで、元の配列は書き換えない
これで、「安全な順序反転」が手に入ります。
動作例
const arr = [1, 2, 3];
const reversed = reverseArray(arr);
console.log(arr); // [1, 2, 3] (元のまま)
console.log(reversed); // [3, 2, 1]
JavaScript「元の配列はそのまま」「逆順の配列は別」という状態になるので、後から見ても混乱しにくくなります。
業務での具体的な使い方
履歴を「新しい順」に並べる
例えば、API が「古い順」で履歴を返してくるケース。
const history = [
{ id: 1, createdAt: "2024-01-01" },
{ id: 2, createdAt: "2024-02-01" },
{ id: 3, createdAt: "2024-03-01" },
];
JavaScript画面では「新しいものから表示したい」ので、順序反転します。
const displayHistory = reverseArray(history);
/*
[
{ id: 3, ... },
{ id: 2, ... },
{ id: 1, ... },
]
*/
JavaScriptここでのポイントは、「API から来た生データはそのまま」「表示用にだけ順序を反転した配列を使う」という分離です。
ログを「直近から」確認したい
ログ配列が古い順で溜まっているとします。
const logs = [
"start",
"step1",
"step2",
"finish",
];
JavaScriptデバッグ時に「直近のログから見たい」なら、逆順にしてから表示します。
const recentFirst = reverseArray(logs);
// ["finish", "step2", "step1", "start"]
JavaScriptこれをコンソールに出したり、画面に出したりするときに、見やすさが一気に変わります。
reverseArray の設計で意識してほしいポイント
非破壊であることを徹底する
順序反転は「破壊的にやるか」「非破壊でやるか」がとても重要です。
- 破壊的:
array.reverse()→ 元の配列が変わる - 非破壊:
array.slice().reverse()→ 新しい配列だけが変わる
業務コードでは、基本的に「非破壊」を選んだほうが安全です。
元の配列をいじると、「どこで順序が変わったのか」が追いにくくなります。
なので、ユーティリティとしては reverseArray のように「必ずコピーしてから反転する」形にしておくのがおすすめです。
「配列じゃないもの」が来ても壊れないようにする
reverseArray は、必ず Array.isArray でチェックしています。
if (!Array.isArray(array)) {
return [];
}
JavaScript現実の業務コードでは、「本当は配列のはずだけど、何かの拍子に null やオブジェクトが来る」ことが普通にあります。
そこで落ちると、「たまにだけ落ちる謎のバグ」になります。
ユーティリティ側で「配列じゃなかったら空を返す」と決めておくと、
呼び出し側は「とりあえず配列が返ってくる」という前提で書けるので、だいぶ楽になります。
少し応用:部分的な順序反転や組み合わせ
一部だけ順序を反転したい
例えば、「全体はそのままだけど、最後の 3 件だけ逆順にしたい」ようなケース。
function reverseLastN(array, n) {
if (!Array.isArray(array) || n <= 0) {
return Array.isArray(array) ? array.slice() : [];
}
const len = array.length;
if (n >= len) {
return reverseArray(array);
}
const head = array.slice(0, len - n);
const tail = array.slice(len - n);
return head.concat(tail.reverse());
}
JavaScript初心者向けには少しステップアップですが、「配列を分割して、片方だけ反転する」という考え方の練習になります。
ソートと組み合わせる
「昇順ソートしたあと、降順で扱いたい」場合も、順序反転が使えます。
const nums = [3, 1, 4, 2];
const asc = nums.slice().sort((a, b) => a - b);
// [1, 2, 3, 4]
const desc = reverseArray(asc);
// [4, 3, 2, 1]
JavaScript「ソート条件を逆に書く」より、「昇順でソートしてから逆順にする」ほうが分かりやすい場面もあります。
手を動かして感覚をつかむ
コンソールで、次のようなコードを実際に打ってみてください。
function reverseArray(array) {
if (!Array.isArray(array)) {
return [];
}
return array.slice().reverse();
}
const arr = [1, 2, 3];
const reversed = reverseArray(arr);
const history = [
{ id: 1, createdAt: "2024-01-01" },
{ id: 2, createdAt: "2024-02-01" },
{ id: 3, createdAt: "2024-03-01" },
];
const displayHistory = reverseArray(history);
JavaScriptarr と reversed の中身、history と displayHistory の順番を見比べて、「元の配列を壊さずに順序だけ反転する」感覚をつかんでみてください。
そのうえで、自分のプロジェクトに
export function reverseArray(...) { ... }
JavaScriptを置き、「配列の順番を逆にしたくなったら、必ずこの“順序反転ユーティリティ”を通す」と決めてみてください。
それだけで、うっかり array.reverse() で元配列を壊してしまうリスクを、かなり減らせます。
