如何在Swift中使用许多唯一键对嵌套JSON进行解码? [英] How to decode a nested JSON with many unique keys in Swift?

查看:68
本文介绍了如何在Swift中使用许多唯一键对嵌套JSON进行解码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是,我可以用来解码具有许多不同密钥的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆