【JavaScript】Arrayのmapメソッドは習うより慣れろって感じ

配列の map() メソッドが使いこなせるようになるとプログラミングが楽しくなってくる。ただ、息をするように使いこなせるようになるには少し練習が必要なので、map() を使う例を集めました。

map() の簡単な例

map() が何をするのかという説明は後回しで、先に例を見てください。

var array = [1, 2, 3]
var newArray = array.map(function (value) {
  return 2 * value
})

console.log(array) // [ 1, 2, 3]
console.log(newArray) // [ 2, 4, 6]

この例を観察すると次のことが見て取れます。

  • map() は配列から配列を作るメソッドである
  • もとの配列は変更されず、新しい配列を作る
  • 引数として関数を渡す
  • 引数となる関数は、もとの配列の各要素を受け取って、新たな配列の要素を返り値としている

つまり map() は、配列の各要素になんらかの操作(ここでは 2 倍にするという操作)をして新たな配列を作ります。

ところで、上の例は JavaScript の書き方としては古いです。ES2015 のアロー関数式を使ってコードを書き直します。

const array = [1, 2, 3]
const newArray = array.map(value => 2 * value)

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

うん、すっきりだ。次からはアロー関数式で書くことにしましょう。

文字列の配列を map で変換する

次は文字列の配列です。配列の各文字列を大文字に変換します。

const array = ['japanese', 'english', 'chinese']
const upper = array.map(language => language.toUpperCase())

console.log(uppere) // [ 'JAPANESE', 'ENGLISH', 'CHINESE' ]

注意点ですが、これは配列の要素がすべて文字列なので .toUpperCase() メソッドを持っていますが、配列の要素に文字列以外のものがあると、エラーになります。.toUpperCase() は文字列のメソッドだからです。

// 要素の一つを数値にした
const array = ['japanese', 'english', 100]
const upper = array.map(language => language.toUpperCase())
// エラーになる!
// TypeError: language.toUpperCase is not a function

配列を map() するときには、各要素の型が同じであるほうがやりやすいと思います。

ただの配列からオブジェクトの配列へ

だんだん楽しくなってきましたね。次は、ただの数値の配列からオブジェクトの配列を作ります。

const array = [1, 2, 3]
const objects = array.map(key => ({ key: key }))

console.log(objects) // [ { key: 1 }, { key: 2 }, { key: 3 } ]

ここで、({ key; key}) というふうにオブジェクトに括弧をつけているのは、アロー関数の都合です。中括弧だけではオブジェクトの外側なのか、(引数) => { 処理 } に出てくる中括弧なのか曖昧なため、エラーになります。

この例はもっと短く書けます。(ES2015 の Shorthand property names)

const objects = array.map(key => ({ key }))

オブジェクトの配列からプロパティの配列へ

さっきと逆に、オブジェクトの配列があったとして、各オブジェクトのあるプロパティだけを取り出した配列を作りましょう。

const persons = [
  { name: 'Alice' },
  { name: 'Bob' },
  { name: 'Charlie' }
]
const names = persons.map(person => person.name)

console.log(keys) // [ 'Alice', 'Bob', 'Charlie' ]

map() の中でインデックスを使う

map() の中で配列のインデックスを使えます。

const array = [5, 5, 5]
array = array.map((value, index) => index)

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

こんな感じで、 map に渡す関数の第二引数が配列のインデックスになります。

使いどころはというと、たとえば 2 つの配列を合体させてオブジェクトの配列を作りたいときに使えます。

// names, ages は同じ長さの配列でないといけない
const names = ['Sato', 'Ito', 'Kato']
const ages = [20, 24, 31]

const persons = names.map((name, i) => ({
  name: names[i],
  age: ages[i]
}))

console.log(persons)
// [ { name: 'Sato', age: 20 },
//   { name: 'Ito', age: 24 },
//   { name: 'Kato', age: 31 } ]

あとはこういうこともできます。

const numbers = Array(5).fill(null).map((_, i) => i + 1)

console.log(numbers) // [ 1, 2, 3, 4, 5 ]

応用すると、”1月” から "12月" までの文字列の配列とかが作れます。

const months = Array(12)
  .fill(null)
  .map((_, i) => i + 1)
  .map(month => month + '月')

console.log(months)
// [
//    '1月',  '2月',
//    '3月',  '4月',
//    '5月',  '6月',
//    '7月',  '8月',
//    '9月', '10月',
//   '11月', '12月'
// ]