I'm looking for an elegant way to select a range of elements in an Array to remove and return, mutating the original array. Javascript has a splice method that serves this purpose but I can't seem to find anything baked into Swift to achieve both steps:
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let oneTwoThree = array.removeAndReturn(0...2) // [1, 2, 3]
// array == [4, 5, 6, 7, 8, 9, 10]
I know about dropFirst(:), prefix(:) and removeSubrange(:) but they all either only return values without mutating the original array, or they mutate the original array without returning values.
Is there another baked-in method I've missed, or would I have to implement a custom extension/method to make this work?
There are removeFirst(), removeLast() and remove(at:) methods which remove
and return a single collection element, but no similar method to remove and return a subrange, so you'll have to implement your own.
A possible implementation is
extension RangeReplaceableCollection {
mutating func splice<R: RangeExpression>(range: R) -> SubSequence
where R.Bound == Index {
let result = self[range]
self.removeSubrange(range)
return result
}
}
Examples:
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8]
print(a.splice(range: 3...4), a) // [3, 4] [0, 1, 2, 5, 6, 7, 8]
print(a.splice(range: ..<2), a) // [0, 1] [2, 5, 6, 7, 8]
print(a.splice(range: 2...), a) // [6, 7, 8] [2, 5]
var data = Data(bytes: [1, 2, 3, 4])
let splice = data.splice(range: 2...2)
print(splice as NSData) // <03>
print(data as NSData) // <010204>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With