简体   繁体   中英

Creating array from AnyObject in Swift

I have an array of AnyObject type like this: [[String : AnyObject]]

animalList = [["name": ABC, "color":red], ["name": DEF, "color": green], ["name": GHI, "color": blue ]]

The model class is like this:

class ModelAnimal {

    var name: String
    var color: String

    init(name: String, color: String){
        self.name = name
        self.color = color 
    }
}

How can I put them in an array of ModelAnimal type:

var myList = Array<ModelAnimal>()

    for var i = 0; i < animalList.count; i++ {

     myList.

    }

Use map to create a new array of type [ModelAnimal] :

let animalList: [[String: AnyObject]] = [["name": "ABC", "color":"red"], ["name": "DEF", "color": "green"], ["name": "GHI", "color": "blue"]]

class ModelAnimal {

    var name: String
    var color: String

    init(name: String, color: String){
        self.name = name
        self.color = color
    }
}

let myList = animalList.map { ModelAnimal(name: $0["name"] as? String ?? "", color: $0["color"] as? String ?? "") }

This also makes use of conditional cast as? String as? String along with the nil coalescing operator ?? to safely extract the values from the array of dictionaries and pass them to the constructor for ModelAnimal .

1. Struct

First suggestion, use a Struct instead of a Class the model.

Why a Struct?

  1. A Struct does allow you to define a failable init that can return fail without initialising all the stored properties.
  2. A Struct is saved into the Stack Memory of your device that is much faster then the heap.
  3. Finally if the name and color field are not going to change you should really declare them as let . This way you Struct is going to be totally immutable (that is good for several reasons).

2. Failable initializer

Add a failable inititializer to your model that receives optional params

struct ModelAnimal {

    let name: String // you can change this back to var if needed
    let color: String  // you can change this back to var if needed

    init(name: String, color: String){
        self.name = name
        self.color = color
    }

    init?(name: String?, color: String?) {
        guard let name = name, color = color else { return nil }
        self.name = name
        self.color = color
    }
}

3. flatMap

Now you can use the powerful flapMap function

let animals = animalList.flatMap { ModelAnimal(name: $0["name"], color: $0["color"]) }

Why flatMap?

  1. The beauty of flatMap is that it does returns only non nil values . Infact animalList contains unstructured data and you have no guarantee (at least at compile time) that each element has a name and a color key. This way if bad data is contained into animalList it is simply discarded.
  2. Another advantage of flatMap is that it does return an array of ModelAnimal , not ModelAnimal? .

First initialize your ModelAnimal objects, then add them to an array:

let animalOne = ModelAnimal(name: "ABC", color: "red")
let animalTwo = ModelAnimal(name: "DEF", color: "green")
let animalThree = ModelAnimal(name: "GHI", color: "blue")

let myList: Array<ModelAnimal> = [animalOne, animalTwo, animalThree]

You could also do this in-line:

let myList: Array<ModelAnimal> = [ModelAnimal(name: "ABC", color: "red"), ModelAnimal(name: "DEF", color: "green"), ModelAnimal(name: "GHI", color: "blue")]

The code just iterates over animalList and adds new items to myList :

var myList = Array<ModelAnimal>()

for var i = 0; i < animalList.count; i++ {
    myList.append(ModelAnimal(name: animalList[i]["name"]!, color: animalList[i]["color"]!))
}

It works, however calling append every time isn't good for performance. Better way to achieve this is to create array with needed length:

for var i = 0; i < animalList.count; i++ {
    myList[i] = ModelAnimal(name: animalList[i]["name"]!, color: animalList[i]["color"]!)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM