map(マップ関数) まっぷ
簡単に言うとこんな感じ!
map は「リストの全員に同じ処理をまとめてやらせる係」だよ!たとえば「社員リスト全員の名前を大文字にして」とか「価格一覧を全部1.1倍にして」みたいな作業を、ループをいちいち書かずにスッキリ1行でこなせる魔法の関数なんだ!
mapとは
map はコレクション(配列やリストなど)の各要素に対して、ある関数を適用し、その結果を新しいコレクションとして返す高階関数です。「高階関数」とは、関数を引数として受け取れる関数のこと。map は「何をするか(処理内容)」を関数として受け取り、「全要素に繰り返し適用する」という仕組みを担います。
ビジネスの場面でイメージすると、「商品リストの価格を全部10%増し」「ユーザー名一覧をすべて大文字に変換」といった「全員に同じ加工を施す」操作が、forループを書かずに宣言的(= “何をしたいか”を直接書くスタイル)に表現できます。これにより、コードの意図が一目でわかりやすくなるのが最大のメリットです。
map は関数型プログラミングの三大コンビネータ(map / filter / reduce)の一角を担い、JavaScriptやPython、Scala、Haskellなど現代のほぼすべての言語に組み込まれています。
mapの構造と動き
基本的な動作イメージ
入力リスト 関数 f 出力リスト
[ 1, 2, 3, 4 ] ──f(x) = x*2──▶ [ 2, 4, 6, 8 ]
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
各要素に f を適用 変換後の新しいリスト
ポイントは元のリストを変更せず、新しいリストを返すところ。これを「イミュータブル(不変)」な操作といいます。
各言語での書き比べ
| 言語 | 記述例 | 備考 |
|---|---|---|
| JavaScript | [1,2,3].map(x => x * 2) | Array.prototype.mapメソッド |
| Python | list(map(lambda x: x*2, [1,2,3])) | 組み込み関数 or リスト内包表記 |
| Ruby | `[1,2,3].map { | x |
| Scala | List(1,2,3).map(x => x * 2) | コレクション全般に対応 |
| Haskell | map (*2) [1,2,3] | 最も純粋な関数型スタイル |
覚え方:「地図(map)に変換を重ねるイメージ」
地図(map)は「ある座標を別の座標に対応させる」もの。数学でも「写像(mapping)」と言い、入力空間の各点を出力空間の点に変換する意味で map という名が使われています。「元の値 → 変換後の値」を1対1で対応させるイメージです。
mapの3つの性質
| 性質 | 内容 | 具体例 |
|---|---|---|
| 全要素適用 | リストの要素すべてに関数を適用する | 1件も飛ばさない |
| 要素数不変 | 入力と出力のリスト長は同じ | 3要素→3要素 |
| 元データ不変 | 元のリストを書き換えない | 新しいリストを返す |
歴史と背景
- 1950年代 — LISPが登場し、関数をデータとして扱う「高階関数」の概念が生まれる。
mapcar(後のmap)がリスト処理の核心的な操作として確立 - 1970〜80年代 — ML・Haskellなど静的型付き関数型言語が発展し、型安全な
mapが普及。map :: (a -> b) -> [a] -> [b]という型シグネチャが定式化される - 1990年代 — Pythonが
map()を組み込み関数として採用。手続き型言語にも関数型の概念が流入し始める - 2000年代 — RubyのEnumerable#map、ScalaのコレクションAPIなど、オブジェクト指向言語がメソッドとして
mapを取り込む - 2011年 — JavaScriptにES5で
Array.prototype.mapが標準化。フロントエンド開発で爆発的に普及 - 2015年以降 — JavaのStream API、C#のLINQなど、エンタープライズ言語にも
map相当の操作が本格導入。「関数型スタイル」が業務系開発の標準になっていく
filter・reduceとの関係:三大コンビネータ
map は単体でも強力ですが、filter・reduce と組み合わせることで真価を発揮します。この3つは「関数型プログラミングの三種の神器」とも呼ばれます。
| 関数 | やること | 例えると |
|---|---|---|
| map | 全要素を変換して新リストを作る | 全員の給料を1.1倍にする |
| filter | 条件を満たす要素だけ残す | 給料30万以上の人だけ抽出 |
| reduce | 全要素をまとめて1つの値にする | 給料の合計を計算する |
3つを組み合わせたパイプライン
社員リスト
│
▼ filter(在籍中の人だけ)
│ [ {name:"田中", active:true}, {name:"山田", active:false}, ... ]
│ ↓ 条件に合う人だけ残す
▼ map(名前だけ取り出す)
│ [ "田中", "佐藤", "鈴木" ]
│ ↓ 変換
▼ reduce(カンマで連結)
"田中, 佐藤, 鈴木"
SVG図解:mapの変換フロー
関連用語
- ./055-filter-function.md — リストから条件を満たす要素だけを取り出す高階関数
- ./057-reduce-function.md — リストの全要素をたたみ込んで1つの値にまとめる高階関数
- ./058-higher-order-function.md — 関数を引数や戻り値として扱う関数の総称
- ./059-lambda.md — 名前を持たない無名関数。mapに渡す処理として頻繁に使われる
- ./060-functional-programming.md — 副作用を避け関数の組み合わせでプログラムを構築するパラダイム
- ./061-immutability.md — データを変更せず新しいデータを返すという考え方。mapの重要な性質
- ./062-iterator.md — コレクションの要素を順番に取り出す仕組み。mapの内部で使われる