21

.remove(at: i) のような種類のインデックスの場所を使用して、配列から複数のアイテムを同時に削除することは可能ですか?

擬似コード:

myArray.remove(at: 3, 5, 8, 12)

もしそうなら、これを行うための構文は何ですか?


更新

私はこれを試していましたが、うまくいきましたが、以下の回答の拡張機能ははるかに読みやすく、賢明であり、疑似コードとまったく同じという目標を達成しています。

「位置」の配列が作成されます: [3, 5, 8, 12]

let sorted = positions.sorted(by: { $1 < $0 })
for index in sorted
{
    myArray.remove(at: index)
}
4

6 に答える 6

37

removeSubrangeメソッドを使用してインデックスが連続している場合は可能です。たとえば、インデックス 3 ~ 5 の項目を削除する場合:

myArray.removeSubrange(ClosedRange(uncheckedBounds: (lower: 3, upper: 5)))

連続していないインデックスの場合は、インデックスが大きい項目から小さい項目に移動することをお勧めします。コードが短くなる可能性があることを除いて、ワンライナーで「同時に」アイテムを削除することについて考えることができる利点はありません。拡張メソッドを使用してこれを行うことができます。

extension Array {
  mutating func remove(at indexes: [Int]) {
    for index in indexes.sorted(by: >) {
      remove(at: index)
    }
  }
}

それで:

myArray.remove(at: [3, 5, 8, 12])

更新: 上記のソリューションを使用すると、インデックス配列に重複したインデックスが含まれていないことを確認する必要があります。または、以下のように重複を避けることができます。

extension Array {
    mutating func remove(at indexes: [Int]) {
        var lastIndex: Int? = nil
        for index in indexes.sorted(by: >) {
            guard lastIndex != index else {
                continue
            }
            remove(at: index)
            lastIndex = index
        }
    }
}


var myArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
myArray.remove(at: [5, 3, 5, 12]) // duplicated index 5
// result: [0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 13] only 3 elements are removed
于 2016-10-11T10:32:42.087 に答える