💮

これからJS沼に足を突っ込もうとしている方に贈る配列操作のいろは

6 min read

はじめに

JavaScriptには配列を操作するメソッドがたくさんあります。勉強し始めは色々ありすぎてごちゃごちゃしてよくわからなくなることがよくあると思います。

実際身近にも、初学者の方で「JSの基本はなんとなくできてちょこちょこVueやReact触ってるけど配列操作苦手!」という方をよく見かけます。個人的にここが明確に理解できていないからかな?と思うポイントがいくつかあるのでまとめてみました。

一概に操作をするといってもメソッドごとに若干考え方が変わります。そのそれぞれの違いをしっかり把握することで頭の中が整理されます。
実際に抑えておきたいポイント整理してみてみましょう!

メソッドを理解するときに重要なポイント(優先度高い順)

  1. 何をするメソッドか
  2. メソッドの引数に何を渡すか
  3. メソッドの戻り値はなにか
  4. 破壊的であるかどうか(とりあえずスルーでもOK)

1~4を意識しながら具体的によく使うメソッドをみていきたいのですが、その前に聞き慣れない言葉もあると思うので軽く説明をしておきます。

1.何をするメソッドか

ここは言わずもがな皆さん考えていると思います。削除するのか、追加するのか、絞り込むのかみたいな話です。
おまけとしてはメソッド名の日本語訳など知っておくともっとイメージ湧きやすいかと思います!意外と意味がわかると何をするのかがわかりやすくなったりします。

2.メソッドの引数に何を渡すか

ここは意識はしているもののそれぞれメソッドごとに色々あって迷いますよね。
これに関しては最初から暗記する必要は無く、使っているうちに調べたりしているとおぼえます。
忘れるたびにググりましょう。

3.メソッドの戻り値はなにか

ここからが初学者の方がつまづきやすいポイントです。
例えば、pushメソッドは配列の末尾に要素を追加します。

const a = [0, 1, 2, 3]
const b = a.push(4)

bには何が入ると思いますか?
[0, 1, 2, 3, 4]ですか?

ぱっとみ[0, 1, 2, 3, 4]とかって思ってしまいますが答えは5です。
pushメソッドは戻り値として要素数を返します。
ちなみに今回はa[0, 1, 2, 3, 4]が入っています。

このようにメソッドごとに実行したときの戻り値が異なる場合があります。
ときには配列を返したり、時には要素数を返したり、、、
MDNにはこんな感じで書かれていますね。

ここも意識してこれからみていきましょう。

4.破壊的であるかどうか

ん・・・・・・? 破壊、的、、?
初学者の方だと初めて聞く方ももしかしたらいるかも知れません。破壊的とは、もとの配列そのものを書き換えてしまう的なイメージでOKです。

例えば先程のコードでaはpushメソッドを使用してしまった後はもとのaは消えてしまって、新しく4が追加された配列になっています。
また、たいてい、破壊的なメソッドの操作には破壊せずに同じような機能を得る代替の実装が存在します。(記事の最後に紹介してます。)

ここを意識するのはもう少し学習を進めた跡かもしれませんが、もしよくわからなければ一旦スルーしても問題ないです。 そういえばそんな話、どっかでみたな〜 くらいでとどめておいて、1〜3をしっかり意識できてればOKです!

// 配列の末尾に要素を追加したい、、!
// 破壊的である例
const a = [1, 2, 3]
a.push(4)
console.log(a) // [1, 2, 3, 4]
// もとの配列aは書き換えられてしまった…

/*====================================*/

// 破壊的でない例
const b = [1, 2, 3]
const c = [...b, 4]
console.log(b) // [1, 2, 3] (もとのbも残ってる!!!)
console.log(c) // [1, 2, 3, 4]

メソッドをみていく前に

この記事では初学者の方に最低限なんとなく知っておいてほしいものだけを厳選してみていきます。
その時のポイントや考え方の参考に慣れば幸いです。また、配列操作のメソッドはたくさんありますが、暗記をしていく必要はありません。

なぜ「なんとなく知っておいてほしい」といったかというと、キーワードさえ覚えておけばググれるからです。よく使うやつはそうやって調べていくうちに自然と覚えます。これは配列操作に限ったことではないですが、調べて使っていれば覚えるので暗記しようとする必要はないです。
肩の力を抜いてそんな心構えでみていきましょう!

よく使う配列操作

1〜4のポイントを意識し、具体例も上げながらよく使うものをみていきましょう!

push

  1. 何をするメソッドか:       配列の末尾に要素を追加する
  2. メソッドの引数に何を渡すか:   追加する要素
  3. メソッドの戻り値はなにか:    新しい配列の要素数
  4. 破壊的であるかどうか:     破壊的

その名の通り要素をプッシュします。

具体例

const countries = ['Japan', 'America', 'China']
countries.push('Brazil')
console.log(countries) // ['Japan', 'America', 'China', 'Brazil']

// 戻り値は新しい配列の要素数
const countryCount = countries.push('England')
console.log(countryCount) // 5
// このときcountriesの中身は
console.log(countries) //['Japan', 'America', 'China', 'Brazil', 'England']

splice

  1. 何をするメソッドか:       配列を切り取って結合
  2. メソッドの引数に何を渡すか:   切り取り開始位置、切り取り数、追加する要素
  3. メソッドの戻り値はなにか:    切り取った配列
  4. 破壊的であるかどうか:     破壊的

spliceは日本語で”接合する”みたいな意味があります。
開始位置を切り取り数を指定して切り取ってくっつけてるイメージですね。
副産物として切り取った後の”切りくず”も手に入ります。

このメソッドはいろんな使い方ができます。それもまとめておきましょう。

用途

  • 特定の要素を切り取り(削除、 複数可)
  • 指定した位置に要素を追加(複数可)
  • 切り取った要素を取得

具体例

// 配列.splice(切り取り開始, 切り取り数, 追加する要素、 追加する要素、・・・)
// 追加する要素は渡さなくても使える。複数渡すこともできる。

const countries = ['Japan', 'America', 'China']

// Chinaを切り取る(2番目から1つ)
countries.splice(2, 1)
console.log(countries) // ['Japan', 'America']

// Japanの後にEnglandとFranceを追加(1番目から0こ削除して要素を加える)
countries.splice(1, 0, 'England', 'France')
console.log(countries) // ['Japan', 'England', 'France', 'America']

// AmericaとEnglndを切り取る
// もどり値は切り取った要素
const newCoutries = countries.splice(1, 2)
console.log(newCoutries) // ['England', 'France']
console.log(countries) // ['Japan', 'America']

forEach

  1. 何をするメソッドか:       要素でループを回してそれぞれに同じ処理をする
  2. メソッドの引数に何を渡すか:   処理をする関数
  3. メソッドの戻り値はなにか:    undefined(特に返さないと思ってOK)
  4. 破壊的であるかどうか:     非破壊的

for Eachなので”それぞれに同じ処理”的な意味合いで覚えておきましょう。

具体例

const numbers = [1, 2, 3]
numbers.forEach(number => {
  console.log(`now number is ${number}`)
})
// 結果
// now number is 1
// now number is 2
// now number is 3

map

  1. 何をするメソッドか:       要素でループを回して同じ処理をして新しい配列を作る
  2. メソッドの引数に何を渡すか:   処理をする関数
  3. メソッドの戻り値はなにか:    新しい配列
  4. 破壊的であるかどうか:     非破壊的

具体例

const numbers = [1, 2, 3]
const doubleNumbers = numbers.map(number => {
 return number * 2
})
console.log(doubleNumbers) // [2, 4, 6]
/*
 * JSの省略法で
 * const doubleNumbers = numbers.map(number => number * 2)
 * みたいに書かれることもありますが、意味は同じ。
 * 実際は短く書きたいので、簡単な処理の場合はこっちがよく使われる
 */

returnの省略について

https://qiita.com/crash-boy/items/f146afd1cdf1e89c4121

filter

  1. 何をするメソッドか:       条件に合う配列を切り出す
  2. メソッドの引数に何を渡すか:   条件を作る関数
  3. メソッドの戻り値はなにか:    条件にあった配列
  4. 破壊的であるかどうか:     非破壊的

具体例

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
// 2で割ったあまりが0のものを抽出して配列にしている(evenNumbersに格納)
const evenNumbers = numbers.filter(number => number % 2 === 0)
console.log(evenNumbers) // [2, 4, 6, 8]

よりよい配列操作ライフを贈るために。。

今回は本当に基本の操作のみを取り上げてみてみました。これ以外にも頻繁に使うものはたくさんあります。その都度ググってみてみましょう。JS <やりたい配列操作の内容>みたいにググれば大抵のものは出てきます。

その時も考えることは同じでです。
引数に何を渡すのか、戻り値は何なのか、、
忘れても使うときにまた同じように調べればよいのです。そうやって繰り返し繰り返し配列の操作に慣れていきましょう。

今日紹介したポイントを押さえればそう難しくはないはずです。何だかなれれば簡単そうに感じませんか?感じますよね?(威圧)
こんな感じで気長に習得していきましょう。

最後まで読んでいただきありがとうございました!

おまけ

冒頭の法で、破壊的なメソッドには代替する非破壊的な操作法があると言いましたが、
それをわかりやすくまとめてくださっている記事があるので紹介させていただきます。

https://noah.plus/blog/007/

あわせてわかりやすい記事も

破壊的?非破壊的?がパット見わかりやすいチートシート

https://qiita.com/Shokorep/items/929e2e66908eaa915286

よく使う配列操作まとめ

https://qiita.com/k-penguin-sato/items/a00f2d9df8cc1e9b7b23