JavaScript | すべての要素に順番に同じ処理を行い、新しい配列を作る

JavaScript JavaScript
スポンサーリンク

map配列の全要素に同じ処理をして、新しい配列を作るメソッド です。元の配列は変わりません(非破壊)。
イメージ:配列の各要素をベルトコンベアで順番に通して「何か加工」し、その結果を別の箱に入れていく感じ。


基本の書き方(超かんたん)

let 新しい配列 = 元の配列.map(function(要素, インデックス, 配列そのもの) {
  // 要素に対する処理
  return 新しい値; // ここが超重要
});
JavaScript

よく使う省略形(アロー関数):

let newArr = arr.map(x => x * 2);
JavaScript
  • 第1引数(必ず受け取れる): 要素の値(例:x
  • 第2引数(任意): その要素のインデックス(何番目か、0から始まる)
  • 第3引数(任意): 元の配列そのもの

map はコールバックの return を集めて新しい配列を作るので、返さないと undefined が入る のに注意。


例題 1 — 文字列を大文字にする(やさしい)

let fruits = ['Apple', 'Grapes', 'Melon', 'Orange'];
let upper = fruits.map(f => f.toUpperCase());
console.log(upper); // ["APPLE","GRAPES","MELON","ORANGE"]
console.log(fruits); // 元の配列はそのまま
JavaScript

ポイント:toUpperCase() を要素ごとに呼んで、新しい配列に入れているだけ。


例題 2 — 数値を 10 倍にする(基本的な数値処理)

let nums = [1, 5, 10];
let times10 = nums.map(n => n * 10);
console.log(times10); // [10, 50, 100]
JavaScript

例題 3 — インデックスを使う(位置情報を利用)

let names = ['Aki', 'Ben', 'Cara'];
let labeled = names.map((name, i) => `${i+1}: ${name}`);
console.log(labeled); // ["1: Aki", "2: Ben", "3: Cara"]
JavaScript

map の第2引数 i(インデックス)が便利。


例題 4 — オブジェクトの配列を変換(実務でよくあるパターン)

たとえば API から来たユーザー配列を別の形に整えるとき:

let users = [
  {id: 1, firstName: 'Sora', lastName: 'Yamada'},
  {id: 2, firstName: 'Mina', lastName: 'Kato'}
];

let display = users.map(u => ({
  id: u.id,
  fullName: `${u.firstName} ${u.lastName}`
}));

/* display は:
[
  {id:1, fullName:"Sora Yamada"},
  {id:2, fullName:"Mina Kato"}
]
*/
JavaScript

ポイント:返す値をオブジェクトにして新しい配列を作れる。


map と forEach の違い(初心者がつまずきやすい点)

  • map必ず配列を返す(コールバックの return を集める)。「変換して新しい配列を作る」ためのもの。
  • forEach:値を返さない(戻り値は undefined)。「順番に何か処理(ログ出力など)をする」ためのもの。

間違い例:

// NG:map の中で console.log だけして return しないと undefined が入る
let a = [1,2,3].map(x => console.log(x));
console.log(a); // [undefined, undefined, undefined]
JavaScript

応用:map をチェーンする(複数ステップの変換)

let numbers = [1,2,3,4];
let result = numbers
  .map(n => n * 2)      // [2,4,6,8]
  .map(n => `No.${n}`); // ["No.2","No.4","No.6","No.8"]
JavaScript

短くて読みやすいが、可読性を保つためにやりすぎに注意。


よくある落とし穴(注意点)

  1. return を忘れると undefined が要素になる。
  2. 元の配列は変更されない が、コールバック内で元配列を直接書き換えると(副作用)元配列が変わるので避けるのがベター。
  3. アロー関数でオブジェクトを返すときは丸括弧が必要:x => ({a: x})。波括弧だけだと関数本体と解釈される。

練習問題

問題 A(やさしい)

配列 [2, 4, 6] の各要素を 3 で割った値の配列を作ってください。
答え(例)

[2,4,6].map(n => n / 3) // [0.666666666..., 1.333..., 2]
JavaScript

問題 B(中級)

次の配列から、price を税込(10%)にした配列を作ってください。

let items = [{name:'Pen', price:100}, {name:'Notebook', price:250}];
JavaScript

答え(例)

items.map(item => ({ name: item.name, priceWithTax: item.price * 1.1 }));
// [{name:'Pen', priceWithTax:110}, {name:'Notebook', priceWithTax:275}]
JavaScript

問題 C(応用)

数字の配列 [3,7,11] を、2乗して文字列 'x^2 = y' の形にした配列を作ってください。
答え(例)

[3,7,11].map(x => `${x}^2 = ${x*x}`)
// ["3^2 = 9", "7^2 = 49", "11^2 = 121"]
JavaScript

まとめ(初心者に覚えてほしい3つ)

  1. map は「要素を変換して新しい配列を作る」ためのメソッド。
  2. コールバックの return が新しい配列の要素 になる。忘れると undefined
  3. 元の配列は壊れない(副作用を避けよう)。オブジェクトを扱うときはコピーを返すのが安全。
タイトルとURLをコピーしました