プログラミング

JavaScript の配列操作に強くなる!

配列操作に強くなりたい

こんにちは!最近少しずつ涼しい日が増えてきて、秋だなぁ〜と感じています。私は寒いのが嫌いなので、ずっとこのままがいいなぁって思っちゃうんですが…

さて、そんな前置きは置いておいて、

最近実務で配列操作をしないといけなかった時に自分が知っているメソッドの種類が少ないせいでググりまくりの時間かかりまくりでかなり苦労したので。。

題名まんまですが、配列操作に強くなりたい…!

ということで今回は、

JavaScript の配列操作に強くなる!

と題して配列の各種メソッドの使い方についてまとめてみたいと思います。

いろいろなメソッド(一部)

配列操作は本当にたくさんのメソッドがあるんですが、全部は書けないので以下自分が使いそうなものの抜粋です。

indexOf()

indexfOf() メソッドは、引数に与えられた内容と同じ内容を持つ配列要素の添字( index )を返します。

【構文】arr.indexOf(searchElement[, fromIndex])

※第1引数:searchElement → 検索する配列要素
※第2引数:fromIndex → 検索を開始する添字

具体例:

// 配列を宣言
const juice = ['orange', 'melon', 'grape', 'apple', 'melon'];
console.log(juice.indexOf('apple')); // 3

// 第二引数を取ることで検索を開始する添字を指定することができる
console.log(juice.indexOf('melon', 2));  // 4

// 第二引数の添字が配列の長さ以上の場合は、-1 を返す
console.log(juice.indexOf('melon', 10));  // -1

// 同じ内容を持つ配列要素が見つからなかった場合は -1 を返す
console.log(juice.indexOf('lemon'));  // -1

 

第2引数の挙動を理解するのに時間がかかったんですけど(汗、6行目を例にすると、juice の配列には、インデックス値1 とインデックス値4 に「 ’melon’ 」要素が存在しますが、

検索開始インデックスとして「 2 」が指定されているのでで、「 ’grape’ 」要素から検索して最初に一致した「 ’melon’ 」の インデックス値 = 4 が返ってくるということなんですね!

あと個人的に、条件に合致する要素が存在しなかった場合に -1 を返すという挙動が面白かったです。0 とか null とかじゃなくて -1 なんだよね…なんでだろ?なんて密かなギモン…

join()

コレは結構わかりやすいやつ。配列の要素を連結するメソッドです。

【構文】arr.join([separator])

※第1引数:separator → 要素を区切る文字列

具体例:

// 配列を宣言
const lunch = ['今日の', 'ランチは', '唐揚げ定食', 'だよ!'];
// 引数に配列を区切る文字列を指定する
console.log(lunch.join('、'));  // 今日の、ランチは、唐揚げ定食、だよ!

// 引数に何も指定しない場合は、コンマで区切られる
console.log(lunch.join());  // 今日の,ランチは,唐揚げ定食,だよ!

// 引数に空文字列('')を指定した場合は、全て要素が区切り文字なしで連結される
console.log(lunch.join(''));  // 今日のランチは唐揚げ定食だよ!

 

こないだランチに唐揚げ定食食べに行こうとしたら、お休みでした。唐揚げ食べたい!(どうでもいい)

spilice()

splice() メソッドは配列の要素の除去・置き換え・追加など行うメソッドで、要素を変更した配列を返します。

【構文】array.splice(start[, deleteCount[, item1[, item2[, …]]]])

※第1引数:start → 変更を開始するインデックス
※第2引数:deleteCount → start のインデックスから削除する要素の数
※第3引数:item1, item2 … → 配列に追加する要素

// 配列を宣言
const wishList1 = ['モニタ', '椅子', 'キーボード', 'ケーブル'];
// インデックス2 以降の要素を削除する
wishList1.splice(2);  
console.log(wishList1);  // ["モニタ", "椅子"]

const wishList2 = ['モニタ', '椅子', 'キーボード', 'ケーブル'];
// インデックス2 の箇所に「'時間'」を追加する
// 第2引数が 0 の場合は配列要素より何も削除しない
wishList2.splice(2, 0, '時間');
console.log(wishList2);  // ["モニタ", "椅子", "時間", "キーボード", "ケーブル"]

const wishList3 = ['モニタ', '椅子', 'キーボード', 'ケーブル'];
// インデックス1 の位置から2つ要素を取り除いて「'時間'」を挿入する
wishList3.splice(1, 2, '時間');
console.log(wishList3); // ["モニタ", 時間", "ケーブル"]

const wishList4 = ['モニタ', '椅子', 'キーボード', 'ケーブル'];
// インデックス1 の位置から3つ要素を取り除いて「'時間'」「'お金'」「'休暇'」を挿入する
wishList4.splice(1, 3, '時間', 'お金', '休暇');
console.log(wishList4);  // ["モニタ", "時間", "お金", "休暇"]

 

上記で wishList1, wishList2, wishList3, wishList4 と配列を4回宣言してるのですが、

spilice は破壊的なメソッドなので、元の配列を直接操作し、破壊してしまいます。

最初は1つの変数使い回しで書こうと思ったんですけど、挙動が変だな?と思って途中で気づきました(汗

配列を直接操作することによってバグの温床になる可能性もあるので、破壊的なメソッドを使うときは注意しないといけないみたいですね。。

slice()

slice() メソッドは、引数に選択した配列の一部の要素をシャローコピーして新しい配列を返します。

【構文】arr.slice([start[, end]])

※第1引数:start → 要素の取り出しを開始するインデックス
※第2引数:end → 要素の取り出しを終える直前のインデックス

// 配列を宣言
const ramen = ['醤油', '味噌', '家系', '魚介とんこつ', '鶏だし'];
// インデックス3 以降の要素を取り出す
console.log(ramen.slice(3)); // '魚介とんこつ', '鶏だし'

// インデックス1からインデックス2 までの要素を取り出す 
// ※ end(第3引数)に指定した直前の要素を取り出すのでインデックス3 の魚介とんこつは取り出されない
console.log(ramen.slice(1, 3));  // '味噌', '家系'

// start(第1引数)に指定したインデックスが実際の配列より大きい場合は、空の配列を返す
console.log(ramen.slice(10));  // [] (空の配列)

 

slice() メソッドは上記の spilice() メソッドと違い、非破壊的なメソッドなので、元の配列を壊しません。

元の配列を壊さず、「シャローコピーして新しい配列を返す」んですが、

「シャローコピー」とはオブジェクトそのものをコピーするのではなく、その参照をコピーするだけなのだそう。なので厳密なコピー(複製)ではないですね。

一方、オブジェクトとメモリ上のデータ両方コピーする場合は「ディープコピー」というそうです。

ちなみに急にオブジェクトが出てきてアレ?って思うかもしれないですが(私だけか?)、配列( Array )もオブジェクト( JavaScript の標準ビルトインオブジェクト)の一種だからなんですね。

まとめ

なんだが MDN 見れば一発で分かることをツラツラ書きましたが…

自分で配列作って、console で出力してみると仕様が理解できて良いですね。

MDN の何が分かりづらいかって、例文が全部英文なのと、ちょっと日本語が怪しい(直訳なのかな?)ところが分かりづらい文章になってるのかな。

って個人的に感じました。

今回書けなかったメソッドは、おいおい別記事でまとめたいと思います。

ここまでお読みいただき、ありがとうございました!