Reputation: 749
I have an array of enums witch contains associated structs like so:
struct TypeOne {
let id = UUID()
var image:UIImage
}
struct TypeTwo {
let id = UUID()
var image:UIImage
var url:URL
}
enum Types {
case one(a: TypeOne)
case two(b: TypeTwo)
}
var array:[Types] = []
Both possible structs share the variables; id and image. Is there any way to retrieve those values without doing like below?
switch array[0] {
case .one(a: let a):
print(a.id)
case .two(b: let b):
print(b.id)
}
Since the two variables are present in both structs I'm looking for a solution like this (if it exists):
print(array[0].(xxx).id)
Upvotes: 0
Views: 97
Reputation: 5073
Someway or another you're going to have to switch over each case to extract the associated values. However, we can make it convenient for use. I'd start with a protocol so our types have a common interface:
protocol TypeProtocol {
var id: UUID { get }
var image: UIImage { get }
}
struct TypeOne: TypeProtocol {
let id = UUID()
var image: UIImage
}
struct TypeTwo: TypeProtocol {
let id = UUID()
var image: UIImage
var url: URL
}
Your enum can largely be the same but we can extend it with some convenient properties.
enum Types {
case one(a: TypeOne)
case two(b: TypeTwo)
}
extension Types: TypeProtocol {
var id: UUID {
type.id
}
var image: UIImage {
type.image
}
var type: TypeProtocol {
switch self {
case .one(let a):
return a
case .two(let b):
return b
}
}
}
Finally, given an array of types we can use the convenience properties to access the underlying data:
var array: [Types] = []
array.forEach { print($0.id) }
array.forEach { print($0.type.id) }
Upvotes: 0
Reputation: 1784
UPDATE: My answer may miss the mark. Do you really need the enum? In my solution the need for the enum was eliminated. But if you need the enum because it carries other significant info, then my solution is no good. If you are just using the enum so you can put both types in an array, then consider using an array of Typeable
instead where Typeable
is the protocol of my solution.
Yes, you could use protocols for something like this to define a common set of methods or fields:
protocol Typeable {
var id:UUID {get}
var image:UIImage {get}
}
struct TypeOne:Typeable {
let id = UUID()
var image:UIImage
}
struct TypeTwo:Typeable {
let id = UUID()
var image:UIImage
var url:URL
}
var array:[Typeable] = []
let typeOne:TypeOne = //
let typeTwo:TypeTwo = //
array.append(typeOne)
array.append(typeTwo)
print(array[0].id)
// to declare a function that takes a Typeable
func myMethod<T:Typeable>(val:T) {
print(val.id)
}
Note, my protocol name is no good and doesn't match naming guidelines. Without knowing more about your use case I'm not sure what a good name would be.
Upvotes: 2