rk-baryoのゆるっと日記

日常生活、ビジネス、旅などについてゆるく語るブログ

【JavaScript】配列の値を削除するときに注意すべきこと

プログラミングの勉強がてら、JavaScriptで自作のwebアプリ的なものを作るようになりました(今のところただの自己満アプリです。。)。

今回は配列の要素(中身)を削除するときに注意すべき点を学んだので、備忘録としてメモ的に紹介します。

プログラミング初心者(IT業務従事者がこれを言ってはいけないはず。。)の戯言と思って読んでいただければ幸いです。

 

削除しないで普通に配列を取り出す場合

まず、以下のような配列があるとします。

f:id:rk-baryo:20191202220421p:plain

これはごく普通の配列で、中身に文字列の「いち」「に」「さん」を格納しているものですね。

次にこの配列をforEachを使って順繰りにコンソール出力してみます。

f:id:rk-baryo:20191202220531p:plain

出力結果は以下のようになります。

f:id:rk-baryo:20191202220648p:plain

この場合、コードと出力結果を見て納得できる方が多いと思います。

deleteで配列要素を消すとどうなるのか

次はこの配列の中の要素を一つ削除してコンソール表示します。

delete 配列名[index]とすると、配列の該当indexの要素を消すことができます。

以下では、array[1]とし、arrayのindex番号1番目、つまり「に」のデータを消しています。

f:id:rk-baryo:20191202221246p:plain

出力結果は以下のようになります。

f:id:rk-baryo:20191202221555p:plain

はい。「に」 が消えました。しっかりdeleteできているようです。ではこの時点で配列の長さはどうなっているのでしょうか。array.lengthを見ます。

f:id:rk-baryo:20191202222039p:plain

f:id:rk-baryo:20191202222102p:plain

要素を一つ削除したにも関わらず、配列の長さは2に減っていないで3のままです。

実はこれが原因で配列のループがうまく回らずに半日近く悩んでしまいました。

色々と調べてみると、どうやらdeleteは配列要素を削除するけれども、中身を「undefined」にするだけで配列の長さは変えないらしいということが分かりました。

上の図では「に」がなくなり、あたかも配列の長さも変更されたかのように見えますが、lengthを取って確認するとそうでないことが分かります。これは知らないと結構ハマるかもしれません。。

長さも変更された配列を取得したいときは

実際には要素をdeleteしたら配列の長さもその分消したいというのが本来の目的だと思います。これを達成する手段は2パターンほど思いつきます。

①splice()を使う

array.splice()を使う方法があります。試しに、先ほどのコードをdeleteではなくspliceで削除したいと思います。

※spliceについて

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

spliceを使って削除

f:id:rk-baryo:20191202222951p:plain

↓ 出力結果

f:id:rk-baryo:20191202223052p:plain

ちゃんとlengthが2に減っているのが分かります。本来欲しかった動作が達成できました。

②delete()とfilter()を組み合わせて使う

filterで特定の条件の要素だけで配列を作り直すことができます。

※filterについて

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

f:id:rk-baryo:20191202223735p:plain

↓ 出力結果

f:id:rk-baryo:20191202223816p:plain

こちらもspliceの時と同様に処理されていることが確認できます。

所感など

今回の記事では配列の要素を削除する方法について少し紹介しました。

今回は普通の配列データを例えて行いましたが、実際にはjson的な中身を持つ配列や連想配列など、色々な配列が存在し、それらに対する処理の仕方はかなりたくさんあるはずです。私もまだまだ勉強中で全然知らないことだらけです。

今回はdeleteという方法が悪いように聞こえるかもしれませんが、配列の要素数はループ処理に影響するため、配列の要素数を変えないで値だけ消したいケースもあります。その場合はdeleteの使い勝手が良いでしょう。

新しく配列の長さも作り直したい場合、index番号が明確に分かるのであればspliceが簡潔な置換方法だと思います。ただ、index番号が分からず、こんなデータを持っているデータは削除したいよ、という場合にはdelete&filterが役に立つのかもしれません。

 

adios