Search code examples
iosarraysswiftxcodeindexpath

Swift 3 Array, remove more than one item at once, with .remove(at: i)


Is it possible to remove more than one item from an array, at the same time, using index locations as per .remove(at: i) kind of like:

Pseudo code:

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

And if so, what's the syntax for doing this?


UPDATE:

I was trying this, it worked, but the extension in the answer below is much more readable, and sensible, and achieves the goal of one that's exactly as the pseudo code.

an array of "positions" is created: [3, 5, 8, 12]

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

Solution

  • It's possible if the indexes are continuous using removeSubrange method. For example, if you would like to remove items at index 3 to 5:

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

    For non-continuous indexes, I would recommend remove items with larger index to smaller one. There is no benefit I could think of of removing items "at the same time" in one-liner except the code could be shorter. You can do so with an extension method:

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

    Then:

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

    UPDATE: using the solution above, you would need to ensure the indexes array does not contain duplicated indexes. Or you can avoid the duplicates as below:

    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