Json:
let json = """
[{
"name":"abc"
"id":"abc123"
"university":"CMU"
},
{
"name":"xyz"
"id":"xyz123"
"university":"NYU"
}]
"""
Struct:
struct Student: Codable {
let name: String
let university: String
}
I know that I can do to get students list
let students = try JSONDecoder().decode([Student].self, from: json.data(using: .utf8)!)
But I am trying to create a dictionary so that I can access any student by student id.
let students = [String:Student]()
- How do I use codable for this problem?
- Is there a way I can use student id as the key and value as a student object?
- I know I can run a loop and append my dictionary, but I am looking for a better solution.
Thank you!
CodePudding user response:
you can use
step 1:
struct Student: Codable {
var name: String = ""
var id: String = ""
var university: String = ""
}
step 2:
let students = try JSONDecoder().decode([Student].self, from: json.data(using: .utf8)!)
let groupedDictionary = Dictionary(grouping: students, by:
{String($0.id)})
CodePudding user response:
You could decode the JSON as unkeyedContainer into a wrapper struct
let json = """
[{
"name":"abc",
"id":"abc123",
"university":"CMU"
},
{
"name":"xyz",
"id":"xyz123",
"university":"NYU"
}]
"""
struct Root : Decodable {
var students = [String:Student]()
init(from decoder: Decoder) throws {
var arrayDecoder = try decoder.unkeyedContainer()
while !arrayDecoder.isAtEnd {
let student = try arrayDecoder.decode(Student.self)
let id = student.id
students[id] = student
}
}
}
struct Student: Decodable {
let name, id, university: String
}
let result = try JSONDecoder().decode(Root.self, from: Data(json.utf8))
print(result.students)
CodePudding user response:
You can simply provide your own subscript for the collections where the Element is Student:
extension Collection where Element == Student {
subscript(_ id: String) -> Element? {
first(where: {$0.id == id})
}
}
struct Student: Codable, Hashable {
let name: String
let id: String
let university: String
}
let json = """
[{
"name":"abc",
"id":"abc123",
"university":"CMU"
},
{
"name":"xyz",
"id":"xyz123",
"university":"NYU"
}]
"""
let students = try JSONDecoder().decode([Student].self, from: Data(json.utf8))
if let student = students["xyz123"] {
print(student.name) // "xyz\n"
print(student.id) // "xyz123\n"
print(student.university) // "NYU\n"
}
