Как получить значения из вложенного JSON Swift - PullRequest
2 голосов
/ 19 марта 2019

Итак, я работал с вложенным файлом JSON (который я добавил локально в свой проект) в Swift.Я включил часть файла 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)
        }
    }
}

Проблема в том, чтоЯ хотел бы получить ВСЕ значения 'categoryName' из файла JSON и ВСЕ значения 'exercInCategory'.Но до сих пор мне удалось только перейти к определенному элементу в файле JSON и получить этот элемент, т.е.

responseJSON.categories[1].categoryName!

Я бы хотел перебрать файл JSON, чтобы получить все значения «categoryName»например.Однако для этого мне нужно написать что-то вроде этого:

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

Где '1' представляет все значения для структуры категорий.Приведенный выше код, очевидно, будет печатать только categoryName второго индекса в массиве категорий в файле JSON.Может ли кто-нибудь указать мне правильное направление?

Ответы [ 6 ]

4 голосов
/ 19 марта 2019

Вы можете сделать это как:

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

Или вы можете использовать map function для получения всех categoryName вроде:

let categoryNames = responseJSON.categories.map {$0.categoryName}
0 голосов
/ 19 марта 2019

Если вы хотите получить весь JSON-файл формы categoryName и exercisesInCategory, вам не нужно передавать жестко закодированный индекс.Используйте следующую модифицированную функцию, она сделает всю работу.

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)
        }
    }
}
0 голосов
/ 19 марта 2019

это.

let categories = responseJSON.categories.map { $0.categoryName }
categories.forEach { print($0) }
0 голосов
/ 19 марта 2019

Если вы хотите поместить оба значения в разные массивы:

var categoryNameList = [String]
var excercisesInCategory = [[String]] 
for category in responseJSON.categories {
    categoryNameList.append(category.categoryName)
    excercisesInCategory.append(category. exercisesInCategory)
}
0 голосов
/ 19 марта 2019

Просто так.

response.categories.forEach { print($0.categoryName) }
0 голосов
/ 19 марта 2019

Если вы перебираете String, то каждый элемент представляет собой один символ строки.


Вы можете перебирать categories массив

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

Комуполучить все имена, вы можете использовать compactMap, который удаляет nil значения из массива

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

Далее:

  • Если каждая категория имеет своиname, сделать тип этого свойства необязательным String (тогда вы можете использовать map вместо compactMap)

  • Я бы улучшил ваше наименование.Переименуйте categoryName ключ json в name, используя CodingKeys enum.Тогда вы могли бы сделать

    category.name
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...