3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

flatMapで配列が残る・undefinedが入る理由:戻り値の形と1段だけの展開をNode.jsで実測

3
Posted at

flatMap()に置き換えたのに配列が残ったり、除外したつもりの位置にundefinedが入ったりする場合、コールバックが返した値の形を調べると切り分けられます。今回は「何でも再帰的に平らにする」とは考えず、返した配列を1段だけ展開する動きを、小さなデータで確かめます。

2026年11月5日、macOS 27.2・Node.js v24.22.1で以下を実行しました。出力の改行は読みやすく整えています。ブラウザやTypeScriptでは試していません。入力は密な通常の配列、コールバックは同期処理に限定します。

rolesを返すか、rolesを包んだ配列を返すか

const users = [
  { name: 'A', roles: ['read', 'write'] },
  { name: 'B', roles: ['read'] },
];

console.log(users.map(u => u.roles));
// [ [ 'read', 'write' ], [ 'read' ] ]

console.log(users.flatMap(u => u.roles));
// [ 'read', 'write', 'read' ]

console.log(users.flatMap(u => [u.roles]));
// [ [ 'read', 'write' ], [ 'read' ] ]

u.rolesは文字列が並んだ配列です。これをそのまま返すと、要素の文字列が結果に入ります。[u.roles]とすると、返した配列の中に、もう1つroles配列が入ります。外側の1段を展開しても内側は残ります。

AIが書いた処理で配列が残ったら、戻り値を1件分取り出して見ます。権限名の一覧が欲しいこの例では、余分な角括弧を外します。

文字列や配列風オブジェクトは展開されない

console.log(['ab', 'cd'].flatMap(s => s));
// [ 'ab', 'cd' ]

console.log([1, 2].flatMap(n => ({ 0: n, length: 1 })));
// [ { '0': 1, length: 1 }, { '0': 2, length: 1 } ]

文字列は文字ごとに分かれません。lengthと数値のキーを持たせても、通常のオブジェクトはそのまま1要素として入りました。ここで展開されるかどうかの境目は「配列として返しているか」です。

除外したいときの戻り値は空配列

console.log([0, 1, 2].flatMap(n => n === 0 ? undefined : [n * 10]));
// [ undefined, 10, 20 ]

console.log([0, 1, 2].flatMap(n => n === 0 ? [] : [n * 10]));
// [ 10, 20 ]

undefinedも配列ではない値なので、1要素として結果に入ります。空配列[]なら、展開して追加する要素が0個になります。これを使うと、入力1件から0件・1件・複数件を返す変換が書けます。

注意したいのは、アロー関数に波括弧を付けたときのreturn忘れです。

console.log([1, 2].flatMap(n => { [n * 10]; }));
// [ undefined, undefined ]

console.log([1, 2].flatMap(n => { return [n * 10]; }));
// [ 10, 20 ]

上側は配列を作る式を評価しただけで、その値を返していません。通常終了して戻り値がundefinedになり、それが結果へ入ります。変換の仕様が「除外」なのか「値の返し忘れ」なのかを、同じものとして扱わないようにします。

確認する順番は、欲しい結果の1要素を決める→コールバックが返す1件分の形を出す→配列ならその1段を外して考える、です。配列が残る場合と、不要な値が入る場合を、戻り値の形から分けて確認できます。

仕様の確認にはMDNのflatMapリファレンスとECMAScriptのArray.prototype.flatMapを参照しました。今回は速度比較や穴の挙動ではなく、戻り値の形と展開の深さに絞りました。


未経験者向けの体験版を公開しています

※ 中上級者には易しすぎる内容なので、初心者の知り合いへの紹介や社内研修の参考としてどうぞ。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?