The Missing Array.appending(contentsOf:)
The Swift standard library has a mutating func append(contentsOf:), but not an immutable variant.
Usually, the Array and Collection types offer both. I wonder why that’s not the case here. To be fair, the concatenation operator + does the same trick.
Here’s a basic implementation I’m using in my apps since forever, but which I haven’t shared, and which I never bothered to store in my code snippets repository (maybe because I believed that this would surely soon be added):
extension Array {
public func appending(contentsOf other: Array<Element>) -> Array<Element> {
var result = self
result.append(contentsOf: other)
return result
}
}
But that’s not very elegant or generic.
Here’s how to find a better base type:
Searching for appending(contentsOf:) in the Swift documentation, a couple of results pop up: Array, ArraySlice, ContiguousArray, Data, RangeReplaceableCollection, Slice, String, Substring, and a couple others even further removed from an array.
So RangeReplaceableCollection is the most generic one I found that would do the trick. Sequence and Collection don’t offer append(contentsOf:), so these are all out.
Checking out append(contentsOf:) will reveal that the parameter can be any Sequence as long as it has the same Element type, which is nice for additional flexibility.
The result is this:
extension RangeReplaceableCollection {
public func appending<Other>(contentsOf other: Other) -> Self
where Other: Sequence, Other.Element == Element {
var result = self
result.append(contentsOf: other)
return result
}
}
That is a drop-in replacement for the Array extension from above, but unlike that, this will also work on Strings and Data etc. as well!
Like the concatenation operator +, this works on mixed left and right hand sides:
"abc".appending(contentsOf: ["d", "e", "f"])