Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge Swift Array with same superclass

Tags:

macos

ios

swift

I'm trying to find the best way to merge Swift arrays, that are not of same type, but they have same superclass. I've already read all the tutorials so I know I can use:

var array = ["Some", "Array", "of", "Strings"]
array += ["Another string", "and one more"]
array.append(["Or", "This"])

In this case array variable infers the type [String]. The problem I have relates to the next hypothetical situation with classes (properties do not matter in this case, just there to make a difference between classes):

class A {
    var property1 : String?
}

class B : A {
    var property2: String?
}

class C : A {
    var property3: String?
}

So I create an array of class A and B objects:

var array = [ A(), B(), A(), B() ]

This array should now be of type [A], since this is the inferred type by both A and B classes.

Now I want to append objects to this array, that are of type C.

var anotherArray = [ C(), C(), C() ]

Since anotherArray is now of type [C], we should still be able to append it, since all C instances respond to A methods. So we try:

array += anotherArray

This fails due to:

Binary operator '+=' cannot be applied to operands of type '[A]' and '[C]'.

Similar story with using append method. While this does make sense, I cannot understand why this couldn't work.

Can someone explain why this is not working? What is the best solution to this problem?

The only sensible solution I found is to define the type of anotherArray to be [A], but are there any better ones or this is correct?

var anotherArray : [A] = [ C(), C(), C() ]

Thanks!

like image 505
Legoless Avatar asked May 11 '15 14:05

Legoless


2 Answers

If C inherits from A then you can "upcast" an array of type [C] to an array of type [A]

array += anotherArray as [A]

Alternatively, use (tested with Swift 4)

array.append(contentsOf: anotherArray)
like image 117
Martin R Avatar answered Nov 14 '22 22:11

Martin R


In addition to Martin's answer, you could create a protocol that all of the classes conform to and then when creating your array, make it's type that protocol.

Then you can add any of the classes to it without casting.

like image 24
Woodstock Avatar answered Nov 14 '22 21:11

Woodstock