[swift-evolution] [Pitch] remove(at: Set<Index>)

Karl razielim at gmail.com
Sat Jun 18 23:09:36 CDT 2016


So like most good pitches, this one comes about because of a bug I recently fixed which seems common and subtle enough that I think it would be nice to include in the standard library.

Removing a collection of elements at once from a collection. You might want to do this in some kind of advanced filtering code. In my case, our code was merging adjacent elements in-place, and storing a list of indexes that were no longer required because they were now part of a merged element, and then we cleaned up the duplicates by removing those indexes.

A näive implementation might look like this:

for index in indexesToRemove {
    myArray.remove(at: index)
}

However, as the array is mutated, those indexes won’t make sense any more. You’ll end up with invalid results - for example, if you have the array [0,1,2] and indexesToRemove is [0,1], your resulting array will actually be [1] (not [2], as expected). Actually removing a batch of indexes is subtly more complex. Here’s my generic implementation:

extension RangeReplaceableCollection where Index:Hashable, Self:BidirectionalIndexable {

	mutating func remove(at indexes: Set<Index>) {
		var removed : IndexDistance = 0
		for idx in indexes.sorted() {
			remove(at: index(idx, offsetBy: -removed))
			removed = removed.advanced(by: 1)
		}
	}
}

I think it would be nice to have this in the standard library. I think it’s a reasonably common problem and it’d be nice to make it easier for people.

Karl




More information about the swift-evolution mailing list