I just learned how to retrieve the attribute keys from a CoreData database and to put them into an array. It's working fine except every time the method runs, it generates the dataset in a different order every time. I just have 3 keys right now - name, sex, type.
Is there something I can do to make it iterate through the keys in the same order each time? I'm going to make more properties and using the information to populate a tableview, so I'd like it to be consistent.
["type", "sex", "name"]
["Goat", "F", "Bob"]
["sex", "name", "type"]
["M", "Jack", "Goat"]
["name", "sex", "type"]
["Bob", "F", "Goat"]
["type", "name", "sex"]
["Goat", "Jack", "M"]
["name", "sex", "type"]
["Bob", "F", "Goat"]
func generateAttributeList(_ animal:Animal) -> Array<String> {
let dictAttributes = animal.entity.attributesByName
var arrAttributeTitles:Array<String> = []
for (key, _) in dictAttributes {
arrAttributeTitles.append(key)
}
return arrAttributeTitles
}
//makes the Value Array
func generateValueList () {
for (name, _) in animal!.entity.attributesByName {
let animalValue = animal!.value(forKey: name) as! String
childValues.append(animalValue)
}
//var attributesByName: [String : NSAttributeDescription] { get }
}
You have some really experienced folks in the comments questioning why you would need to do this and pointing out there may be a better approach. But if you decide you really need to do this, this is how you can.
Return the keys sorted, you don't really need to copy them, so your first function would look like this.
func generateAttributeList(_ animal:Animal) -> [String] {
let dictAttributes = animal.entity.attributesByName
return dictAttributes.keys.sorted()
}
Then pass the keys into the function that returns the values to produce the values in order.
func generateValueList (order: [String]) -> [String] {
var childValues = [String]()
for key in order {
let animalValue = animal!.value(forKey: key) as! String
childValues.append(animalValue)
}
return childValues
}
Or more succinctly
func generateValueList (order: [String]) -> [String] {
return order.map { animal!.value(forKey: $0) as! String }
}