JavaScript Tips | 配列ユーティリティ:先頭取得

JavaScript JavaScript
スポンサーリンク

何をしたいユーティリティか:「先頭取得」

ここでの「先頭取得」は、配列の「一番最初の要素」や「先頭から数件」を取り出す処理のことです。
英語だと headfirsttake などと呼ばれます。

業務では、例えば次のような場面でよく使います。

検索結果の「最初の 1 件」だけを使いたい。
ソート済みデータの「最小(または最大)を表す 1 件目」だけ欲しい。
「先頭 5 件だけプレビュー表示」して、「もっと見る」で残りを出したい。

毎回 array[0]slice(0, n) を直書きしても動きますが、
ユーティリティとして名前を付けておくと、「何をしたいコードなのか」が一気に読みやすくなります。


一番基本:先頭の 1 要素を安全に取得する

素朴な書き方と、その問題点

JavaScript で「先頭の 1 要素」を取る一番素朴な書き方は、これです。

const first = array[0];
JavaScript

ただし、業務コードでは次のような問題が出てきます。

arraynullundefined の可能性がある。
array が配列でない可能性がある。
空配列のときにどう扱うかを毎回考えないといけない。

そこで、「安全に先頭要素を取得する」ユーティリティを用意しておきます。

安全な first ユーティリティ

function first(array, defaultValue = undefined) {
  if (!Array.isArray(array) || array.length === 0) {
    return defaultValue;
  }
  return array[0];
}
JavaScript

ここが重要ポイントです。

Array.isArray で「本当に配列か」を確認していること。
配列でない、または空配列なら defaultValue を返すこと。
呼び出し側が「空のときに何を返してほしいか」を指定できること。

これにより、「null かもしれない配列」「空かもしれない配列」に対しても、
毎回 if 文を書かずに済みます。

実際の動き

first([1, 2, 3]);              // 1
first([], null);               // null
first(null, "なし");           // "なし"
first(undefined);              // undefined
first("not array", "default"); // "default"
JavaScript

「空のときにどうするか」を defaultValue で決められるのが、実務ではかなり効いてきます。


先頭から複数件を取得する:take 的なユーティリティ

「1 件」ではなく「先頭 N 件」が欲しい場面

プレビュー表示や、件数制限と組み合わせるときなど、
「先頭から N 件だけ欲しい」という場面も多いです。

素朴には array.slice(0, n) で書けますが、
やはり「安全性」と「意図の見やすさ」のためにユーティリティ化しておきます。

take ユーティリティ

function take(array, count) {
  if (!Array.isArray(array)) {
    return [];
  }

  if (count == null) {
    return array.slice();
  }

  if (count <= 0) {
    return [];
  }

  return array.slice(0, count);
}
JavaScript

ここでの重要ポイントは次の通りです。

配列でなければ空配列を返す。
countnull / undefined なら「制限なし」とみなして全部返す。
count <= 0 のときは空配列を返す。
それ以外は slice(0, count) で先頭から count 件だけを返す。

これで、「先頭 N 件だけ欲しい」という処理を、毎回同じルールで書けるようになります。

実際の動き

const data = [1, 2, 3, 4, 5];

take(data, 3);      // [1, 2, 3]
take(data, 10);     // [1, 2, 3, 4, 5]
take(data, 0);      // []
take(data, -1);     // []
take(data, null);   // [1, 2, 3, 4, 5]
take(null, 3);      // []
JavaScript

「0 以下は 0 件」「null は制限なし」というルールをユーティリティ側で固定しておくと、
呼び出し側が迷わなくなります。


先頭取得を業務でどう使うか

例1:検索結果の「最初の 1 件」だけを使う

検索 API が「候補の配列」を返してくるとします。
そのうち「最初の 1 件だけを採用したい」場合、こう書けます。

const candidates = await searchSomething(query);
const best = first(candidates, null);

if (!best) {
  // 見つからなかったときの処理
} else {
  // best を使った処理
}
JavaScript

first を使うことで、「先頭の候補を取っている」という意図がコードから読み取れます。
candidates && candidates[0] のような書き方より、ずっと意味が明確です。

例2:ソート後の「最小(または最大)」を取る

例えば、「価格の安い順にソートして、最も安い商品だけを表示したい」場合。

const sorted = [...products].sort((a, b) => a.price - b.price);
const cheapest = first(sorted, null);
JavaScript

「ソート後の先頭要素=最小値」というパターンはよく出てきます。
ここでも first を使うことで、「先頭を取っている」ことがはっきりします。

例3:先頭数件だけプレビュー表示する

一覧画面で、「とりあえず先頭 3 件だけ表示して、『もっと見る』で残りを出す」ような UI もよくあります。

const previewItems = take(items, 3);
const hasMore = Array.isArray(items) && items.length > previewItems.length;
JavaScript

take を使うことで、「先頭から N 件だけを取っている」ことが明確になり、
slice(0, 3) があちこちに散らばるのを防げます。


「先頭取得」ユーティリティ設計で意識してほしいポイント

1. 「空のとき」の扱いを毎回決めなくてよいようにする

先頭取得で一番面倒なのは、「空配列だったときどうするか?」を毎回考えることです。

undefined をそのまま返すのか。
null を返すのか。
特定のデフォルト値を返すのか。

first(array, defaultValue) のように、「空のときは defaultValue を返す」と決めておけば、
呼び出し側は「空なら null でいい」「空なら 0 でいい」など、用途に応じて選べます。

ここをユーティリティに閉じ込めることで、
「毎回 if (!array || array.length === 0) と書く地味なストレス」から解放されます。

2. 「配列でないもの」が来ても壊れないようにする

現実の業務コードでは、「本当は配列のはずだけど、何かの拍子に null やオブジェクトが来る」ことが普通にあります。
そこで落ちると、ユーザーから見て「たまにだけ落ちる謎のバグ」になります。

Array.isArray でチェックし、配列でなければ「空扱い」にしてしまうのは、
「壊れないこと」を優先した設計です。

もちろん、「配列でなければ例外を投げる」ポリシーもありえますが、
フロントエンドやバッチ処理では「とりあえず安全側に倒す」ほうが現実的なことが多いです。

3. 「1 件」と「複数件」を関数で分ける

firsttake を分けておくと、コードの意図がとても読みやすくなります。

first は「1 件だけ欲しい」。
take は「先頭から N 件欲しい」。

どちらも内部的には array[0]slice(0, n) を使いますが、
関数名で「何をしたいのか」を表現しておくと、
未来の自分やチームメイトがコードを読むときに助かります。


少し手を動かして感覚をつかむ

コンソールで、次のようなコードを実際に打ってみてください。

const data = [1, 2, 3, 4, 5];

first(data);
first([], "empty");
first(null, "none");

take(data, 2);
take(data, 10);
take(data, 0);
take(null, 3);

const products = [
  { name: "A", price: 300 },
  { name: "B", price: 100 },
  { name: "C", price: 200 },
];

const sorted = [...products].sort((a, b) => a.price - b.price);
const cheapest = first(sorted, null);
JavaScript

「空のときに何が返ってくるか」「先頭 N 件がどう切り出されるか」「ソート後の先頭取得がどう動くか」を、自分の目で確認してみてください。

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

export function first(...) { ... }
export function take(...) { ... }
JavaScript

のような関数を置き、「配列の先頭を取りたくなったら、必ずこの“先頭取得ユーティリティ”を通す」というルールを作ってみてください。
そうすると、「場当たり的な array && array[0]」から、「意図と安全性を兼ね備えた先頭取得」に一段ステップアップしていきます。

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