I like the pure Swift solution, i.e. without accessing NSIndexSet:
extension Array { mutating func removeAtIndexes (ixs:[Int]) -> () { for i in ixs.sorted(>) { self.removeAtIndex(i) } } }
EDIT In Swift 4 it will be:
extension Array { mutating func remove (at ixs:[Int]) -> () { for i in ixs.sorted(by: >) { self.remove(at:i) } } }
But years after I wrote this answer, a video about using WWDC algorithms in 2018 indicates a disadvantage: this is O (n 2 ), because the remove(at:) command itself must go through the array.
According to this video, Swift 4.2 removeAll(where:) efficient because it uses semi-stable splitting. So we could write something like this:
extension Array { mutating func remove(at set:IndexSet) { var arr = Swift.Array(self.enumerated()) arr.removeAll{set.contains($0.offset)} self = arr.map{$0.element} } }
My tests show that despite contains repeatedly, which is 100 times faster. However, the @vadian approach is 10 times faster than the one because it deploys contains , brilliantly strolling through the index set at the same time it was walking around the array (using semi-stable partitioning).
matt
source share