Home > Mobile >  Equivalent to a JS array of objects in Swift. My current implementation throws an error 'proper
Equivalent to a JS array of objects in Swift. My current implementation throws an error 'proper

Time:05-23

I want my users to loop through an interface where they see a picture and can press a button to generate a sound that belongs to the picture.

To do that, I am trying to build a data structure in Swift that holds two key-value pairs so that I can call the value of each property at the current index of wherever my user happens to be.

One of the properties is an image with a UIImage value and the other is a sound with a string value. After trying several things, the best I could come up with is the below implementation but that throws the following error at each of the variables in my animals variable. Error: Cannot use instance member 'bird' within property initializer; property initializers run before 'self' is available.

When I declare the animals variable with local scope, i.e. inside a function, it works fine. But I need that variable to have global scope. I've been searching quite a bit and have to admit I don't completely understand the error that's been thrown.

Can anyone point out what I am doing wrong?

Code in XCode:

class element {
    let image : UIImage
    let sound : String
    init (image : UIImage, sound : String) {
            self.image = image
            self.sound = sound
        }
}

let monkey = element(image : UIImage(named: "Baviaan")!, sound : "monkey")
let donkey = element(image : UIImage(named: "Donkey")!, sound : "donkey")
let horse = element(image : UIImage(named: "Horse")!, sound : "horse")
let lion = element(image : UIImage(named: "Leeuw")!, sound : "lion")
let elephant = element(image : UIImage(named: "Olifant")!, sound : "elephant")
let sheep = element(image : UIImage(named: "Sheep")!, sound : "sheep")
let dog = element(image : UIImage(named: "Tekkel")!, sound : "dog")
let chicken = element(image : UIImage(named: "toktok")!, sound : "chicken")
let bird = element(image : UIImage(named: "birds")!, sound : "bird")

var animals = [bird,chicken,dog,donkey,elephant,horse,lion,monkey,sheep]

Pic of error:

screenshot of problem

CodePudding user response:

This kind of a global variable is bad practice. Don't do that. A better way is a static property

struct Element {
    let image : UIImage
    let sound : String

    static let animals = [
        Element(image: UIImage(named: "Baviaan")!, sound: "monkey"),
        Element(image: UIImage(named: "Donkey")!, sound: "donkey"),
        Element(image: UIImage(named: "Horse")!, sound: "horse"),
        Element(image: UIImage(named: "Leeuw")!, sound: "lion"),
        Element(image: UIImage(named: "Olifant")!, sound: "elephant"),
        Element(image: UIImage(named: "Sheep")!, sound: "sheep"),
        Element(image: UIImage(named: "Tekkel")!, sound: "dog"),
        Element(image: UIImage(named: "toktok")!, sound: "chicken"),
        Element(image: UIImage(named: "birds")!, sound: "bird")
   ]
}

or shorter

struct Element {
    let image : UIImage
    let sound : String
    
    static let animals = [
        ("Baviaan", "monkey"), ("Donkey", "donkey"),
        ("Horse", "horse"), ("Leeuw", "lion"),
        ("Olifant", "elephant"), ("Sheep", "sheep"),
        ("Tekkel", "dog"), ("toktok", "chicken"), ("birds", "bird")]
        .map{Element(image: UIImage(named: $0.0)!, sound: $0.1)}
}

You get the animals with

Element.animals
  • Related