如何从嵌套JSON Swift检索值

时间:2019-03-19 08:58:47

标签: ios arrays json swift dictionary

所以我一直在Swift中处理嵌套的JSON文件(我在本地将其添加到项目中)。我在下面包含了我正在处理的JSON文件的一部分。数据的结构如下:

{
    "categories": [
                   {
                   "categoryName": "Albatrosses",
                   "exercisesInCategory": [
                                           "Wandering albatross",
                                           "Grey-headed albatross",
                                           "Black-browed albatross",
                                           "Sooty albatross",
                                           "Light-mantled albatross"
                                           ]
                   },
                   {
                   "categoryName": "Cormorants",
                   "exercisesInCategory": [
                                           "Antarctic shag",
                                           "Imperial shag",
                                           "Crozet shag"
                                           ]
                   },
                   {
                   "categoryName": "Diving petrels",
                   "exercisesInCategory": [
                                           "South Georgia diving petrel",
                                           "Common diving petrel"
                                           ]
                   },
                   {
                   "categoryName": "Ducks, geese and swans",
                   "exercisesInCategory": [
                                           "Yellow-billed pintail"
                                           ]
                   }
                   ]
}

为了检索数据,我制作了2个结构来表示JSON中的数据,因此可以从中检索值。如下:

struct Response:Codable{
    let categories: [Categories]
}

struct Categories:Codable{
    let categoryName : String?
    let exercisesInCategory : [String]
}

文件名为fitnessData.json,我正在尝试使用以下代码从其中检索数据:

    private func parse(){
    print("Retrieving JSON Data...")
    if let url = Bundle.main.url(forResource: "fitnessData", withExtension: "json") {

        do {
            let data = try Data(contentsOf: url)
            self.response = try JSONDecoder().decode(Response.self, from: data)

            if let responseJSON = self.response {

                print("The categories are: ", responseJSON.categories[1].categoryName!)
            }
        } catch {
            print(error)
        }
    }
}

问题是我想从JSON文件中检索所有“ categoryName”值,以及所有“ exercisesInCategory”值。但是到目前为止,我只设法导航到JSON文件中的特定项目并检索该项目,即。

responseJSON.categories[1].categoryName!

例如,我想遍历JSON文件以获取所有的'categoryName'值。但是,为了做到这一点,我必须写这样的东西:

for value in responseJSON.categories[1].categoryName! {
                    print(value)
                }  

其中“ 1”代表类别struct的所有值。上面的代码显然将仅打印JSON文件中category数组中第二个索引的categoryName。有人可以指出我正确的方向吗?

6 个答案:

答案 0 :(得分:4)

您可以这样做:

for category in responseJSON.categories {
     print(category.categoryName!)
}

或者您可以使用map函数来获取所有categoryName,例如:

let categoryNames = responseJSON.categories.map {$0.categoryName}

答案 1 :(得分:0)

如果您迭代String,则每个项目都是字符串的单个字符。


您可以遍历categories数组

for category in responseJSON.categories {
    print(category.categoryName ?? "No name")
}

要获取所有名称,可以使用compactMap从数组中删除nil

let names = responseJSON.categories.compactMap { $0.categoryName }

下一步:

  • 如果每个类别都有其名称,请将此属性的类型设置为非可选String(然后您可以使用map代替compactMap

  • 我会改善您的命名。使用categoryName枚举将json的name键重命名为CodingKeys。那你可以做

    category.name
    

答案 2 :(得分:0)

就是这样。

response.categories.forEach { print($0.categoryName) }

答案 3 :(得分:0)

如果要将两个值都放在不同的数组中:

var categoryNameList = [String]
var excercisesInCategory = [[String]] 
for category in responseJSON.categories {
    categoryNameList.append(category.categoryName)
    excercisesInCategory.append(category. exercisesInCategory)
}

答案 4 :(得分:0)

这个。

let categories = responseJSON.categories.map { $0.categoryName }
categories.forEach { print($0) }

答案 5 :(得分:0)

如果您想获取所有categoryNameexercisesInCategory形式的JSON文件,则无需传递硬编码索引。使用以下修改的功能,它将完成工作。

private func parse(){
    print("Retrieving JSON Data...")
    if let url = Bundle.main.url(forResource: "fitnessData", withExtension: "json") {
        do {
            let data = try Data(contentsOf: url)
            let response = try JSONDecoder().decode(Response.self, from: data)

            for category in response.categories {
                print("Category Name: \(category.categoryName!)")

                for exercises in category.exercisesInCategory {
                    print("Exercise in category: \(exercises)")
                }
            }
        } catch {
            print(error)
        }
    }
}