配列の要素で条件に合う値を複数削除したいなーって思ったことありませんか?
先ほど想定通りいかなかったパターンがあったのでご紹介します。
for文で要素をひとつずつチェックして条件にあう要素を削除しようとしたら
var alphabets = ["a", "b", "c", "d", "e"] for (i, alphabet) in alphabets.enumerated() { if alphabet == "a" || alphabet == "d" { alphabets.remove(at: i) } } print(alphabets)
最後のprint分の結果が
["b", "c", "d"]
ん???
d 消えてない?代わりに e が消えたぞ?
これ調べてみたら、「enumerated()」がindexを返しているわけではなく、単にカウントアップで数字を返しているだけなのが原因みたいでした。
a を消した時点で、[“b”, “c”, “d”, “e”]となって、 d の i は 3 なので配列の3番目である e が削除されてしまう、といった具合ですね。。。(配列の要素は 0 始まり)
ちなみに、条件を d から e に変えると(if alphabet == “a” || alphabet == “e”)
... Index out of range ...
まあ、そうなりますよね。
zip(_, _)を使うといいよというのがいくつか出てきたんですが、他に解決方法ないのかなと考えていたら
後ろの要素から消せばいいのでは!?ということで「.reversed()」を入れてみました。
var alphabets = ["a", "b", "c", "d", "e"] for (i, alphabet) in alphabets.enumerated().reversed() { if alphabet == "a" || alphabet == "d" { alphabets.remove(at: i) } } print(alphabets)
結果は
["b", "c", "e"]
期待通りの動きになりました!
(利用する際は、自己責任でお願いします)
コメント