JavaScript | 配列・オブジェクト:配列の変換・加工 – flat

JavaScript JavaScript
スポンサーリンク

flat とは何か

flat は「“入れ子(ネスト)になった配列”を、指定した深さまで“平坦化(フラットに)して新しい配列”を返す」メソッドです。元の配列は変更しない非破壊操作です。ここが重要です:flat は“配列の中の配列”だけを展開します。オブジェクトや値は展開されず、深さの指定でどこまで平坦化するかをコントロールできます。


基本の使い方と深さ指定

1階層だけ平坦化する(既定の深さは 1)

const nested = [1, [2, 3], [4, [5]]];
const flat1 = nested.flat();
console.log(flat1); // [1, 2, 3, 4, [5]]
JavaScript

ここが重要です:デフォルトは深さ 1。外側のひとつ内側の配列だけが展開され、さらに深い配列はそのまま残ります。

深さを指定してさらに平坦化

const nested = [1, [2, [3, [4]]]];
const flat2 = nested.flat(2);
console.log(flat2); // [1, 2, 3, [4]]
JavaScript

ここが重要です:flat(depth) の depth は「何段階展開するか」。2 を指定すれば2層分展開されます。必要な深さを最小にすると意図が明確になります。

すべての階層を平坦化(Infinity)

const deep = [1, [2, [3, [4, [5]]]]];
const flatAll = deep.flat(Infinity);
console.log(flatAll); // [1, 2, 3, 4, 5]
JavaScript

ここが重要です:階層が不定のデータに対して、一気に完全平坦化したいときは Infinity が便利です。ただし計算量が増えるため、必要な場面に限定しましょう。


欠損・空スロットと flat の挙動

空要素(疎配列の“穴”)は削除される

const sparse = [1, , [2, , 3]]; // カンマ連続は“空スロット”
const out = sparse.flat();
console.log(out); // [1, 2, 3](穴は消える)
JavaScript

ここが重要です:flat は疎配列の空スロットを“スキップ”して詰めます。穴を保持したい場面では、事前に Array.from で正規化するなど設計を見直してください。

undefined 値は残る(空スロットと区別)

const arr = [undefined, [undefined, 1]];
console.log(arr.flat()); // [undefined, undefined, 1]
JavaScript

ここが重要です:値としての undefined はそのまま残ります。空スロットとの違いを理解しておくと、意図しない欠損が防げます。


実務での定番パターン

map で配列を返したあとに1階層だけフラット化

const users = [{id:1,tags:["js","web"]},{id:2,tags:["ai"]}];
const allTags = users.map(u => u.tags).flat(); // [["js","web"],["ai"]] → ["js","web","ai"]
JavaScript

ここが重要です:“配列の配列”を作る処理(例えば map)と flat は強力な相性。処理を分けると読みやすく、デバッグもしやすいです。

flatMap で“変換+1階層平坦化”を1回で

const users = [{tags:["js","web"]},{tags:["ai"]}];
const allTags = users.flatMap(u => u.tags); // ["js","web","ai"]
JavaScript

ここが重要です:flatMap は「map の返り値を 1 階層だけ自動で flat」します。毎回 1 階層が確定しているなら flatMap が最短です。

ネストした結果を結合して一覧に

const groups = [
  { name: "A", items: [1, 2] },
  { name: "B", items: [3] }
];
const allItems = groups.map(g => g.items).flat(); // [1, 2, 3]
JavaScript

ここが重要です:ネスト構造の“中身の統合”に flat は最適。concat 連発より短く、意図が明確に伝わります。


パフォーマンスと選択の指針

必要最小の深さで使う

深さを大きくすると探索量が増えます。構造が分かっているなら、flat(1) や flat(2) など必要最小で十分です。未知の深さで Infinity を使う場合は、データ量と頻度に留意しましょう。

多階層の大規模データは専用手段も検討

深い木構造の平坦化が頻繁なら、再帰関数やスタックベースのイテレーションを自前で設計する方が、途中で条件分岐(フィルタ、型判定)を挟みやすく柔軟です。要件が複雑なときは flat だけに頼らず、明示的なロジックにすると読みやすさが上がります。


よくある落とし穴と回避策

“配列以外”は展開されない

flat は「配列の中の配列」だけを展開します。オブジェクトを展開したい場合は map でプロパティを取り出すなど、変換ステップを挟みます。

const rows = [{ cols: [1,2] }, { cols: [3] }];
const flatCols = rows.map(r => r.cols).flat(); // [1,2,3]
JavaScript

文字列を分解したいときは別メソッド

文字列は配列ではないので flat では分解されません。split などを使います。

const s = "a,b,c";
const arr = s.split(","); // ["a","b","c"]
JavaScript

flatMap の返すものは“配列”に限らないが、配列以外はそのまま

flatMap のコールバックが配列以外を返すと、そのまま値が入ります。1階層だけ展開されるのは“配列を返した部分”だけです。混在させると読みづらくなるため、返す型を揃えましょう。


実践例(UI・データ整形・API)

テーブルのセルを1本のリストへ

const table = [
  ["A1","A2"],
  ["B1"],
  ["C1","C2","C3"]
];
const cells = table.flat(); // ["A1","A2","B1","C1","C2","C3"]
JavaScript

カテゴリ別の商品リストから全商品一覧へ

const catalog = {
  fruits: ["apple","banana"],
  vegs: ["carrot"]
};
const all = Object.values(catalog).flat(); // ["apple","banana","carrot"]
JavaScript

多段のメニューを表示用に平坦化(必要な深さだけ)

const menu = [
  { label: "File", children: ["New","Open"] },
  { label: "Edit", children: ["Copy", ["Paste", "Undo"]] }
];
const items = menu.map(m => m.children).flat(1); // ["New","Open","Copy", ["Paste", "Undo"]]
JavaScript

まとめ

flat は「入れ子になった配列を指定深さまで平坦化して“新しい配列”を返す」非破壊メソッドです。デフォルトは 1 階層、全階層は Infinity。疎配列の“穴”は削除されますが、値としての undefined は残ります。map で配列を返した後の統合や、flatMap での“変換+1階層平坦化”が実務の定番。配列以外は展開されない点、深さは必要最小にする指針、複雑な要件では専用ロジックも検討する、を押さえれば、初心者でも意図通りで壊れにくい“平坦化処理”を短く明確に書けます。

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