0

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:

  1. the append method is crossed out in autofill, so I am not sure if I should use it.
  2. Even if I try to use it (while it's being crossed out), it is still giving me errors

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?

4
  • 3
    if one of them is optional, you can for example var1 + (var2 ?? []) By the way [Data] and Array<Data> is literally the same thing. The ? makes the difference. Commented Feb 6, 2019 at 19:16
  • @Sulthan Thank you that's it, solved it! Commented Feb 6, 2019 at 19:23
  • @Sulthan you should post your comment as an answer. The optional think is the answer. Commented Feb 6, 2019 at 20:22
  • 3
    Do not edit answers into the question. Either wait for @Sulthan to post his comment as an answer, or answer it yourself. Commented Feb 6, 2019 at 21:35

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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 ?? [])
    }
}

1 Comment

How about if the optional would be on the left side of the operand? Addition should be commutative. But would it make sense to add something to a nil array?
1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.