James James - 5 months ago 17
Swift Question

Swift initialise empty array to store different structs later

I have a couple of different types of structs (Promo & Event). I'd like to create an empty array which gets populated with an array of each type depending on the outcome of an

if
statement.

So something like this:

var dataArray:[Any] = [] // see options I've tried below

if myTest == true {
dataArray = [Promo, Promo, Promo]
} else {
dataArray = [Event, Event, Event]
}


I have tried using:

1. var dataArray: [Any] = []
2. var dataArray: [AnyObject] = []
3. var dataArray: [Any] = [Any]()
4. var dataArray: [AnyObject] = [AnyObject]()


but when I try to store an array of
Promo
Structs in
dataArray
I get an error
Cannot assign value of type '[Promo]' to type '[Any]'
etc.

So, how do I initialise an array so that it can store a variety of (unknown) Structs. Or how do I modify my Structs to enable them to be stored in an array?

I'm really struggling to see what I'm doing wrong so any pointers would be v. helpful.




Here are my Structs:
Promo.swift

import Foundation

struct Promo {

// initialise the stored properties for use later
let promoId : Int
let date : NSDate
let title: String
let body: String
let busName : String
let busId : Int
let categoryId: Int
let featured: Bool

// a universal init() method which has optional parameters
init(promoId: Int,
date: NSDate,
title: String,
body: String,
busName: String,
busId: Int,
categoryId: Int,
featured: Bool
){
self.promoId = promoId
self.date = date
self.title = title
self.body = body
self.busName = busName
self.busId = busId
self.categoryId = categoryId
self.featured = featured
}
}

// allow us to compare structs
extension Promo: Equatable {}
func ==(lhs: Promo, rhs: Promo) -> Bool {
return lhs.promoId == rhs.promoId
&& lhs.date == rhs.date
&& lhs.title == rhs.title
&& lhs.body == rhs.body
&& lhs.busName == rhs.busName
&& lhs.busId == rhs.busId
&& lhs.categoryId == rhs.categoryId
&& lhs.featured == rhs.featured
}


Event.swift

import Foundation

struct Event {

// initialise the stored properties for use later
let eventId : Int
let date : NSDate
let title: String
let body: String
let busName : String
let busId : Int
let categoryId: Int

// a universal init() method which has optional parameters
init(eventId: Int,
date: NSDate,
title: String,
body: String,
busName: String,
busId: Int,
categoryId: Int
){
self.eventId = eventId
self.date = date
self.title = title
self.body = body
self.busName = busName
self.busId = busId
self.categoryId = categoryId
}
}

Answer

If you are trying to assign to dataArray from [Promo] or [Event] arrays, you could map:

var dataArray:[Any] = []
var promoArray:[Promo] = [Promo(), Promo(), Promo()]
var eventArray:[Event] = [Event(), Event(),Event()]

if myTest == true {
    dataArray = promoArray.map { $0 as Any }
} else {
    dataArray = eventArray.map { $0 as Any }
}

Or create new Any arrays:

if myTest == true {
    dataArray = Array<Any>(arrayLiteral: promoArray)
} else {
    dataArray = Array<Any>(arrayLiteral: eventArray)
}