如何在Swift中使用许多唯一键对嵌套JSON进行解码? [英] How to decode a nested JSON with many unique keys in Swift?
问题描述
我的问题是,我可以用来解码具有许多不同密钥的JSON的最佳方法是什么?现在,我正在为每个单个对象创建一个变量.这似乎效率低下/很难编码,我大约有8种不同的菜单可以解码.
My questions is what is the best method I could use to decode a JSON that has many different keys? Right now, I am creating a var for every single one. This seems inefficient/hard coding, and I have about 8 different menus like this to decode.
这是我的JSON :(很长,我知道)
Here is my JSON: (long, I know)
{
"Brunch": {
"BEAR FIT": [
"Savory Tofu, Spinach, Tomato Scramble"
],
"BEAR FUSION": [
"Roasted Red & Gold Beets",
"Baked Ham",
"Parslied Potatoes",
"Roasted Zuchhini Squash Medley",
"Vegan Celebration Roast",
"Steamed Rice",
"Brown Rice"
],
"BEAR NECESSITIES": [
"Rolled Oatmeal",
"Italian Wedding Soup"
],
"BEAR SWEETS": [
"Blueberry Muffin",
"Cranberry Orange Scone",
"Assorted Danish"
],
"BREAKFAST PLATE": [
"Hashbrown Tri Patty",
"Spiced French Toast",
"Breakfast Veggie Patty"
],
"GOLDEN GRILL": [
"Waffle Bar Toppings"
],
"ITALIAN CORNER": [
"Omelet Bar"
],
"PASTAS": [
"Breadsticks",
"Pasta",
"Whole Wheat Pasta",
"Creamy Alfredo Sauce",
"Beef Bolognese Sauce"
],
"SMOOTHIES": [
"Peach Smoothie"
],
"SPECIALTY SALADS": [
"Macaroni Salad"
]
},
"Dinner": {
"BEAR FIT": [
"Vegetable Caribbean Blend",
"Three Bean Chili",
"Brown Rice"
],
"BEAR FUSION": [
"Chicken Vindaloo",
"Chana Masala",
"Brown Rice",
"Steamed Rice"
],
"BEAR NECESSITIES": [
"Garden Vegetable Soup with Tomato",
"Italian Wedding Soup"
],
"BEAR SWEETS": [
"Raspberry Sammie",
"Chocolate Chunk Brownie",
"Pumpkin Pie"
],
"CAL-ZONE": [
"Mushroom & Olive Flatbread",
"Meat Lovers Pizza",
"Pepperoni Pizza"
],
"GOLDEN GRILL": [
"Fish Sandwich",
"Malibu Burger",
"Shoestring Fries"
],
"PASTAS": [
"Breadsticks",
"Pasta",
"Whole Wheat Pasta",
"Creamy Alfredo Sauce",
"Beef Bolognese Sauce"
],
"SPECIALTY SALADS": [
"Macaroni Salad"
],
"THE BIG C": [
"Hawaiian BBQ Pork",
"Blackened Tilapia with Lemon Pepper",
"Teriyaki Tofu",
"Steamed Rice",
"Suateed Cabbage",
"Cinnamon Glazed Carrot"
]
}
}
这是我现在拥有的解析器:
Here is my parser that I have now:
struct WeekendMenu: Decodable {
struct Brunch: Decodable {
var BEAR_FIT: [String]
var BEAR_FUSION: [String]
var BEAR_NECESSITIES: [String]
var BEAR_SWEETS: [String]
var BREAKFAST_PLATE: [String]
var GOLDEN_GRILL: [String]
var ITALIAN_CORNER: [String]
var PASTAS: [String]
var SMOOTHIES: [String]
var SPECIALTY_SALADS: [String]
private enum CodingKeys: String, CodingKey {
case BEAR_FIT = "BEAR FIT"
case BEAR_FUSION = "BEAR FUSION"
case BEAR_NECESSITIES = "BEAR NECESSITIES"
case BEAR_SWEETS = "BEAR SWEETS"
case BREAKFAST_PLATE = "BREAKFAST PLATE"
case GOLDEN_GRILL = "GOLDEN GRILL"
case ITALIAN_CORNER = "ITALIAN CORNER"
case PASTAS = "PASTAS"
case SMOOTHIES = "SMOOTHIES"
case SPECIALTY_SALADS = "SPECIALTY SALADS"
}
}
struct Dinner: Decodable {
//TODO
}
var brunch: String
var dinner: String
private enum CodingKeys: String, CodingKey {
case brunch = "Brunch"
case dinner = "Dinner"
}
}
推荐答案
在这种情况下,我建议将JSON解码为字典 [String:[String]]
In this case I recommend to decode the JSON as dictionaries [String:[String]]
struct WeekendMenu: Decodable {
private enum CodingKeys : String, CodingKey { case brunch = "Brunch", dinner = "Dinner" }
let brunch: [String:[String]]
let dinner: [String:[String]]
}
枚举字典,对键进行排序以获得相同的顺序
Enumerate the dictionaries, sort the keys to get the same order
let result = try JSONDecoder().decode(WeekendMenu.self, from: data)
for key in result.brunch.keys.sorted() {
print(key, result.brunch[key]!)
}
for key in result.dinner.keys.sorted() {
print(key, result.dinner[key]!)
}
或者编写一个自定义初始化程序,将字典解码为自定义结构 Category
,键变成 name
,值变成 dishes
数组.
Alternatively write a custom initializer to decode the dictionaries into a custom struct Category
, the key becomes the name
, the value becomes the dishes
array.
struct WeekendMenu: Decodable {
private enum CodingKeys : String, CodingKey { case brunch = "Brunch", dinner = "Dinner" }
let brunch: [Category]
let dinner: [Category]
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let brunch = try container.decode([String:[String]].self, forKey: .brunch)
let brunchKeys = brunch.keys.sorted()
self.brunch = brunchKeys.map { Category(name: $0, dishes: brunch[$0]!) }
let dinner = try container.decode([String:[String]].self, forKey: .dinner)
let dinnerKeys = dinner.keys.sorted()
self.dinner = dinnerKeys.map { Category(name: $0, dishes: dinner[$0]!) }
}
}
struct Category {
let name : String
let dishes : [String]
}
这篇关于如何在Swift中使用许多唯一键对嵌套JSON进行解码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!