[英]JSON into array of custom objects (Swift)
我有一个JSON,我需要将其转换为对象数组。 这是我的JSON(它的简短版本)
[
{
"categoryID": 5,
"categoryDescription": "Trips",
"groupID": 43,
"groupDescription": "USA",
"groupImage": "e613c87a-4dab-4929-90cf-2b584fdf0399.jpg",
"subgroupDescription": "2 days",
"subgroupPrice": "200"
},
{
"categoryID": 5,
"categoryDescription": "Trips",
"groupID": 43,
"groupDescription": "USA",
"groupImage": "e613c87a-4dab-4929-90cf-2b584fdf0399.jpg",
"subgroupDescription": "5 days",
"subgroupPrice": "500"
},
{
"categoryID": 5,
"categoryDescription": "Trips",
"groupID": 33,
"groupDescription": "Mexico",
"groupImage": "e613c87a-4dab-4929-90cf-2b584fdf0399.jpg",
"subgroupDescription": "3 days",
"subgroupPrice": "400"
},
{
"categoryID": 5,
"categoryDescription": "Trips",
"groupID": 33,
"groupDescription": "Mexico",
"groupImage": "e613c87a-4dab-4929-90cf-2b584fdf0399.jpg",
"subgroupDescription": "1 days",
"subgroupPrice": "150"
},
{
"categoryID": 3,
"categoryDescription": "Hotels",
"groupID": 22,
"groupDescription": "My Hotel",
"groupImage": "e613c87a-4dab-4929-90cf-2b584fdf0399.jpg",
"subgroupDescription": "1 night",
"subgroupPrice": "50"
},
{
"categoryID": 3,
"categoryDescription": "Hotels",
"groupID": 10,
"groupDescription": "Your Hotel",
"groupImage": "e613c87a-4dab-4929-90cf-2b584fdf0399.jpg",
"subgroupDescription": "2 nights",
"subgroupPrice": "150"
}]
并且我需要制作一个这样的自定义对象:(如何在Swift 4中创建这样的对象?)
在JSON中,我们有categoryID和groupID,我需要基于它们过滤数组,例如,我只需要一个具有categoryID 5的对象,而我只需要一个具有groupID的对象:43。但是我需要所有子组。 这是我的对象的结构:(我不知道我走的路是否正确)
struct Categories {
var categoryID: NSNumber
var categoryDescription: String
var groups : [Groups]}
struct Groups {
var geoupID: NSNumber
var geoupDescription: String
var groupImage: String
var subGroups : [Subgroups] }
struct Subgroups {
var subgroupPrice: NSNumber
var subgroupDescription: String }
如何以最佳方式过滤它?
至于如何制作结构,只需使用Decodable
并根据您在JSON中的期望命名字段,或使用CodingKeys
指定名称。 例如:
struct MyStruct: Decodable {
let categoryID: Int
let categoryDescription: String
let groupID: Int
// …
}
然后,您可以使用JSONDecoder
将结果解码为[MyStruct]
。
现在,真正的问题似乎是您希望内部拥有与JSON接收的不同的结构,包括诸如“每个categoryID
只有一个”之categoryID
约束。 然后,最直接的方法可能是遍历解码结果并将内容复制到不同的结构中。
代替数组(例如, var groups: [Groups]
),您可以使用具有groupID
作为键的字典来强制每个ID中只有一个,例如:
guard let results = try? jsonDecoder.decode([MyStruct].self, from: json) else { return }
var categories = [Int: Category]()
for result in results {
// fetch existing category or make a new one
var category = categories[result.categoryID, default: Category(id: result.categoryID, description: result.categoryDescription)]
// fetch existing group in category or make a new one
var group = category.groups[result.groupID, default: Group(id: result.groupID, description: result.groupDescription, image: result.groupImage)]
// append subgroup (always new since there is no id)
let subgroup = Subgroup(description: result.subgroupDescription, price: result.subgroupPrice)
group.subgroups.append(subgroup)
// "save"
category.groups[result.groupID] = group
categories[result.categoryID] = category
}
国家杰森
{
ID = 2;
Image = "";
Name = "";
City = (
{
ID = 74;
Name = "";
ParentID = 2;
},
{
ID = 79;
Image = "";
Name = Other;
ParentID = 2;
}
);
},
{
ID = 31;
Image = "";
Name = "";
City = (
{
ID = 99;
Name = "";
ParentID = 31;
},
{
ID = 100;
Name = "";
ParentID = 31;
});
}
我的课
class Country: Codable {
var id: String?
var image: String?
var name: String?
var cityList: [City]?
enum CodingKeys: String, CodingKey {
case id = "ID"
case image = "Image"
case name = "Name"
case city = "City"
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try? values.decode(String.self, forKey: .id)
image = try? values.decode(String.self, forKey: .image)
name = try? values.decode(String.self, forKey: .name)
cityList = try? values.decode([City].self, forKey: .city)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(image, forKey: .image)
try container.encode(name, forKey: .name)
try container.encode(cityList, forKey: .city)
}
}
class City: Codable {
var id: String?
var name: String?
var parentId: String?
enum CodingKeys: String, CodingKey {
case id = "ID"
case name = "Name"
case parentId = "ParentID"
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try? values.decode(String.self, forKey: .id)
name = try? values.decode(String.self, forKey: .name)
parentId = try? values.decode(String.self, forKey: .parentId)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
try container.encode(parentId, forKey: .parentId)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.