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"]
JavaScriptflatMap の返すものは“配列”に限らないが、配列以外はそのまま
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階層平坦化”が実務の定番。配列以外は展開されない点、深さは必要最小にする指針、複雑な要件では専用ロジックも検討する、を押さえれば、初心者でも意図通りで壊れにくい“平坦化処理”を短く明確に書けます。
