Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A simple "splice" type method on Array in Swift?

Tags:

arrays

swift

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?

like image 634
Aaron Avatar asked Mar 21 '26 12:03

Aaron


1 Answers

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>
like image 166
Martin R Avatar answered Mar 24 '26 03:03

Martin R