Reputation: 571
I know this sounds ridiculous but I am seriously confused now.
Basically I have two vars, one is [Data]
and one is Array<Data>?
I need to combine these two.
I've tried do var1+var2
, which is giving me errors say can't do binary operations on these two.
So I googled, I can use append method, now there comes more questions:
Here is the code and errors I get:
var a1:[Data] //a return value from other function
var a2:Array<Data>? //a parameter that's passed in
a1.append(contentsOf:a2) //Cannot use mutating member on immutable value: function call returns immutable value
a1+a2 //Binary operator '+' cannot be applied to operands of type 'Array<Data>' and 'Array<Data>?'
Both arrays can be empty, how can I concatenate these two arrays?
Upvotes: 0
Views: 1215
Reputation: 236420
You can also extend RangeReplaceable Collection and implement a custom append method as well as addition and mutating addition operators as follow:
extension RangeReplaceableCollection {
public mutating func append<S: Sequence>(contentsOf sequence: S?) where Element == S.Element {
guard let sequence = sequence else { return }
reserveCapacity(count + sequence.underestimatedCount)
append(contentsOf: sequence)
}
}
extension RangeReplaceableCollection {
public static func += <S: Sequence>(lhs: inout Self, rhs: S?) where Element == S.Element {
guard let rhs = rhs else { return }
lhs.reserveCapacity(lhs.count + rhs.underestimatedCount)
lhs.append(contentsOf: rhs)
}
}
extension RangeReplaceableCollection {
public static func + <S: Sequence>(lhs: Self, rhs: S?) -> Self where Element == S.Element {
guard let rhs = rhs else { return lhs }
var result = Self()
result.reserveCapacity(lhs.count + rhs.underestimatedCount)
result.append(contentsOf: lhs)
result.append(contentsOf: rhs)
return result
}
}
Playground Testing
var a1 = "abc"
let a2: String? = "d"
let a3: String? = nil
let a4: [Character]? = ["e","f"]
a1 + a2 + a3 + a4 // "abcdef"
a1 + a2
print("a1:", a1)
a1 += a2
print("a1:", a1)
a1 + a3
print("a1:", a1)
a1 += a3
print("a1:", a1)
a1 + a4
print("a1:", a1)
a1 += a4
print("a1:", a1)
a1.append(contentsOf: ["e","f","g"])
print("a1:", a1)
a1.append(contentsOf: "hijkl")
print("a1:", a1)
Upvotes: 1
Reputation: 7096
Sulthan's answer is the quick solution, but if you do this a lot in your code, you can overload +
to handle it for you automatically:
extension Array {
static func + (lhs: [Element], rhs: [Element]?) -> [Element] {
return lhs + (rhs ?? [])
}
}
Upvotes: 1
Reputation: 130122
One of the arrays is optional. You have to handle the possible nil
value somehow.
A simple solution using nil-coalescing:
let concatenated = var1 + (var2 ?? [])
or, slightly more complex:
var concatenated = var1
if let var2 = var2 {
concatenated.append(var2)
}
There are other possible solutions, of course.
Upvotes: 2