ユーニックス総合研究所

  • home
  • archives
  • js-map

JavaScriptのmapの使い方: 配列に一括処理をして新しい配列を作成する

  • 作成日: 2020-08-14
  • 更新日: 2023-12-28
  • カテゴリ: JavaScript

mapの使い方

JavaScriptの配列にはmapというメソッドがあります。
これを使うと配列に対して一括処理をしたあとに、新しく配列を作成することが出来ます。
for文などのループ文を使う必要もないので非常にお手軽です。

たとえば配列内の値を2倍して、その結果を新しい配列に保存する場合は↓のようになります。

const arr1 = [1, 2, 3]  
const arr2 = arr1.map(el => el * 2)  

console.log(arr2)  
// [ 2, 4, 6, ]  

↑の場合、arr1という配列をmap()で回してarr2を作成しています。
arr1の各要素が2倍されてarr2に保存されていきます。
結果はconsole.log()の通りです。

mapの引数

mapには関数を渡します。
この関数は配列の要素を走査するたびに呼ばれます。
関数の引数には走査中の配列の要素が渡されます。

const arr = [1, 2, 3]  

// 普通の関数を使う場合  
arr.map(function (el) {  
    return el * 2  
})  

// アロー関数を使う場合  
arr.map(el => el * 2)  

関数は戻り値を返すようにします。
この戻り値はmapが作成する配列に格納されます。
functionの関数ではreturnを書いておかないと値が格納されませんので注意が必要です。

mapに渡す関数の引数

mapに渡す関数の引数ですが、関数の第1引数には配列の要素が渡されます。

const arr1 = [1, 2, 3]  
const arr2 = arr1.map((el) => {  
    return el  
})  

console.log(arr2)  
// [ 1, 2, 3 ]  

第2引数には走査中のインデックスが渡されます。
これはfor文などで言うカウント変数に当たります。

const arr1 = [1, 2, 3]  
const arr2 = arr1.map((el, index) => {  
    return index  
})  

console.log(arr2)  
// [ 0, 1, 2 ]  

第3引数には走査中の配列自身が渡されます。
↓の場合arr1meは同じものです。

const arr1 = [1, 2, 3]  
const arr2 = arr1.map((el, index, me) => {  
    return me[index]  
})  

console.log(arr2)  
// [ 1, 2, 3 ]  

mapの第2引数

mapの第2引数にはthisに相当するオブジェクトを渡すことが出来ます。

function CheckMe () {  
    this.sum = 0  
}  

const checkMe = new CheckMe()  
const arr1 = [1, 2, 3]  

arr1.map(function (el) {  
    this.sum += el  // <- このthisはcheckMeを指している  
}, checkMe)  // <- checkMeを参照させる  

console.log(checkMe.sum)  
// 6  

thisを動的に変更できるので↑のようにfunctionの中のthisの参照先を変えることが可能です。

CheckMeはメンバにsum変数を持っています。そしてこれをcheckMe変数にインスタンス化しています。
配列arr1mapで参照するときに、第2引数にcheckMeを渡すことで、mapで呼ばれる関数内のthischeckMeになります。
アロー関数ではなく普通の関数を使っていることに注意してください。
上記のコードをアロー関数にするとうまく機能しません。

mapの使用例

mapは、たとえば配列の各要素にフィルターをかけたい場合に使えます。
配列内の大文字のアルファベットの文字列を全て小文字にしたいとします。

普通のfor文を使った場合は↓のようになるでしょう。

const arr1 = [  
    'CAT',  
    'DOG',  
    'BIRD',  
]  
let arr2 = []  

for (const el of arr1) {  
    arr2.push(el.toLowerCase())  
}  

console.log(arr2)  
// [ 'cat', 'dog', 'bird' ]  

↑のコードはarr1内の文字列をすべて小文字にする処理です。
for文を使うと一般的には↑のようなコードになります。

いっぽう、mapを使うと↓のように書けます。

const arr1 = [  
    'CAT',  
    'DOG',  
    'BIRD',  
]  
const arr2 = arr1.map(el => el.toLowerCase())  

console.log(arr2)  
// [ 'cat', 'dog', 'bird' ]  

普通のfor文と比べるとmapのほうがいくぶんスッキリしてますね。
map()にはアロー関数を渡していることに注意してください。
アロー関数は波カッコを省略するとreturnを書かなくても戻り値が返ります。

さらに関数lowerを定義しておけばもっとスッキリ書くことが出来ます。

function lower(s) {  
    return s.toLowerCase()  
}  

const arr1 = [  
    'CAT',  
    'DOG',  
    'BIRD',  
]  

const arr2 = arr1.map(lower)  // <- ここら辺がスッキリ  

console.log(arr2)  
// [ 'cat', 'dog', 'bird' ]  

lower関数のように要素に対してフィルターを適用する関数をモジュール化しておいて、使う時はmapに渡す、というような設計にするとコードがカッコよくなるかもしれません。
ほかには文字を大文字にするupper関数も定義しておくと便利になるでしょう。

問題

Q1: mapの第1引数に渡せるものを答えよ

  1. オブジェクト
  2. 配列
  3. 関数

Q2: mapに渡すコールバック関数の第2引数の役割を答えよ

  1. 要素の参照
  2. 配列の参照
  3. 添え字の参照

Q3: mapの使い方で適当なものを答えよ

  1. フィルター
  2. 配列の走査
  3. オブジェクトの走査

答え
Q1: 3
Q2: 3
Q3: 1, 2