JavaScript Tips | 配列ユーティリティ:順序反転

JavaScript JavaScript
スポンサーリンク

何をしたいユーティリティか:「順序反転」

「順序反転」は、配列の要素の並びを逆向きにする処理です。
[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 は「元の配列そのもの」を書き換える
  • 戻り値も同じ配列への参照なので、arrreversed は同じもの

業務コードでこれをうっかり使うと、「どこかで順序が勝手に変わっている」ようなバグにつながりやすいです。

非破壊版の順序反転ユーティリティ

そこで、「元の配列は変えずに、逆順の新しい配列を返す」ユーティリティを用意します。

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);
JavaScript

arrreversed の中身、historydisplayHistory の順番を見比べて、「元の配列を壊さずに順序だけ反転する」感覚をつかんでみてください。

そのうえで、自分のプロジェクトに

export function reverseArray(...) { ... }
JavaScript

を置き、「配列の順番を逆にしたくなったら、必ずこの“順序反転ユーティリティ”を通す」と決めてみてください。
それだけで、うっかり array.reverse() で元配列を壊してしまうリスクを、かなり減らせます。

タイトルとURLをコピーしました