何をしたいユーティリティか:「末尾取得」
ここでの「末尾取得」は、配列の「一番最後の要素」や「末尾から数件」を取り出す処理のことです。
英語だと last や takeRight などと呼ばれます。
業務では、例えば次のような場面でよく使います。
ログの「最新 1 件」だけを見たい。
履歴の「直近 5 件」だけを表示したい。
ソート済みデータの「最大値(最後の 1 件)」を取りたい。
毎回 array[array.length - 1] や slice(-n) を直書きしても動きますが、
ユーティリティとして名前を付けておくと、「何をしたいコードなのか」が一気に読みやすくなります。
一番基本:末尾の 1 要素を安全に取得する
素朴な書き方と落とし穴
JavaScript で「末尾の 1 要素」を取る一番素朴な書き方は、これです。
const last = array[array.length - 1];
JavaScriptただし、業務コードでは次のような問題が出てきます。
array が null や undefined の可能性がある。array が配列でない可能性がある。
空配列のときに array.length - 1 が -1 になり、array[-1] は undefined になる。
毎回これを意識するのはしんどいので、「安全な末尾取得ユーティリティ」を用意します。
安全な last ユーティリティ
function last(array, defaultValue = undefined) {
if (!Array.isArray(array) || array.length === 0) {
return defaultValue;
}
return array[array.length - 1];
}
JavaScriptここが重要ポイントです。
Array.isArray で「本当に配列か」を確認していること。
配列でない、または空配列なら defaultValue を返すこと。
呼び出し側が「空のときに何を返してほしいか」を指定できること。
これにより、「null かもしれない配列」「空かもしれない配列」に対しても、
毎回 if 文を書かずに済みます。
実際の動き
last([1, 2, 3]); // 3
last([], null); // null
last(null, "なし"); // "なし"
last(undefined); // undefined
last("not array", "default"); // "default"
JavaScript「空のときにどうするか」を defaultValue で決められるのが、実務ではかなり効いてきます。
末尾から複数件を取得する:takeLast 的なユーティリティ
「1 件」ではなく「末尾 N 件」が欲しい場面
ログや履歴、タイムラインなどでは、「末尾から N 件だけ欲しい」という場面が多いです。
素朴には array.slice(-n) で書けますが、
やはり「安全性」と「意図の見やすさ」のためにユーティリティ化しておきます。
takeLast ユーティリティ
function takeLast(array, count) {
if (!Array.isArray(array)) {
return [];
}
if (count == null) {
return array.slice();
}
if (count <= 0) {
return [];
}
if (array.length <= count) {
return array.slice();
}
return array.slice(array.length - count);
}
JavaScriptここでの重要ポイントは次の通りです。
配列でなければ空配列を返す。count が null / undefined なら「制限なし」とみなして全部返す。count <= 0 のときは空配列を返す。
配列長が count 以下なら、そのまま全部返す。
それ以外は「末尾から count 件」を slice で切り出す。
slice(-count) でも書けますが、「長さを意識したほうが初心者には分かりやすい」ので、あえて length - count で書いています。
実際の動き
const data = [1, 2, 3, 4, 5];
takeLast(data, 2); // [4, 5]
takeLast(data, 10); // [1, 2, 3, 4, 5]
takeLast(data, 0); // []
takeLast(data, -1); // []
takeLast(data, null); // [1, 2, 3, 4, 5]
takeLast(null, 3); // []
JavaScript「0 以下は 0 件」「null は制限なし」というルールをユーティリティ側で固定しておくと、
呼び出し側が迷わなくなります。
末尾取得を業務でどう使うか
例1:ログの「最新 1 件」を見る
ログ配列が時系列順(古い → 新しい)で積み上がっているとします。
「最新ログだけを見たい」場合、こう書けます。
const latest = last(logs, null);
if (!latest) {
// ログがないときの処理
} else {
// latest を使った処理
}
JavaScriptlast を使うことで、「末尾の要素を取っている」という意図がコードから読み取れます。logs && logs[logs.length - 1] のような書き方より、ずっと意味が明確です。
例2:履歴の「直近 N 件」だけを表示する
ユーザーの操作履歴などを、「直近 10 件だけ」画面に出したい場合。
const recent = takeLast(history, 10);
JavaScriptこれだけで、「末尾から 10 件だけ」を安全に取り出せます。slice(-10) をあちこちに書くより、「意図が名前に出ている」ほうが読みやすいです。
例3:ソート後の「最大値」を取る
例えば、「価格の安い順にソートして、最も高い商品だけを表示したい」場合。
const sorted = [...products].sort((a, b) => a.price - b.price);
const mostExpensive = last(sorted, null);
JavaScript「ソート後の末尾要素=最大値」というパターンはよく出てきます。
ここでも last を使うことで、「最後を取っている」ことがはっきりします。
「末尾取得」ユーティリティ設計で意識してほしいポイント
1. 「空のとき」の扱いを毎回決めなくてよいようにする
先頭取得と同じく、末尾取得で一番面倒なのは、「空配列だったときどうするか?」を毎回考えることです。
undefined をそのまま返すのか。null を返すのか。
特定のデフォルト値を返すのか。
last(array, defaultValue) のように、「空のときは defaultValue を返す」と決めておけば、
呼び出し側は「空なら null でいい」「空なら 0 でいい」など、用途に応じて選べます。
ここをユーティリティに閉じ込めることで、
「毎回 if (!array || array.length === 0) と書く地味なストレス」から解放されます。
2. 「配列でないもの」が来ても壊れないようにする
現実の業務コードでは、「本当は配列のはずだけど、何かの拍子に null やオブジェクトが来る」ことが普通にあります。
そこで落ちると、ユーザーから見て「たまにだけ落ちる謎のバグ」になります。
Array.isArray でチェックし、配列でなければ「空扱い」にしてしまうのは、
「壊れないこと」を優先した設計です。
takeLast も同様に、「配列でなければ空配列」を返すようにしておくと、
呼び出し側は「とりあえず配列として扱ってよい」という前提で書けます。
3. 「先頭取得」と対になる API にしておく
first と last、take と takeLast のように、
「先頭系」と「末尾系」をペアで用意しておくと、API 設計としてとても気持ちよくなります。
first / last … 1 要素だけ欲しい。take / takeLast … 先頭/末尾から N 件欲しい。
名前と挙動が対称になっていると、
「先頭でこれができるなら、末尾も同じ感じで書けるよね」と直感的に分かります。
少し手を動かして感覚をつかむ
コンソールで、次のようなコードを実際に打ってみてください。
const data = [1, 2, 3, 4, 5];
last(data);
last([], "empty");
last(null, "none");
takeLast(data, 2);
takeLast(data, 10);
takeLast(data, 0);
takeLast(null, 3);
const logs = [
{ at: "10:00", msg: "A" },
{ at: "10:05", msg: "B" },
{ at: "10:10", msg: "C" },
];
const latest = last(logs, null);
const recentTwo = takeLast(logs, 2);
JavaScript「空のときに何が返ってくるか」「末尾 N 件がどう切り出されるか」「ログの最新がどう取れるか」を、自分の目で確認してみてください。
そのうえで、自分のプロジェクトに
export function last(...) { ... }
export function takeLast(...) { ... }
JavaScriptのような関数を置き、「配列の末尾を取りたくなったら、必ずこの“末尾取得ユーティリティ”を通す」というルールを作ってみてください。
そうすると、「場当たり的な array[array.length - 1]」から、「意図と安全性を兼ね備えた末尾取得」に一段ステップアップしていきます。
