Разбор JSON с похожими элементами с использованием SwiftyJSON - PullRequest
0 голосов
/ 16 октября 2018

У меня есть этот тип JSON (просто короткий пример):

"orderProducts": [
        {
            "id": 135,
            "order_id": 39,
            "product_id": 49,
            "product_code": "",
            "size_id": 13,
            "quantity": 2,
            "product": {
                "id": 49,
                "code": "",
                "factory_id": 2,
                "product_category_id": 1,
                "sex_id": null,
                "season_id": null,
                "product_type_id": null,
                "type_id": null,
                "color_id": null,
                "year_id": null,
                "image_1": "bceef8b28ae2a1797ca0c6300021100d.jpeg",
                "image_2": "",
                "image_3": "",
                "notes": "",
                "status": 10
            }
        },
        {
            "id": 136,
            "order_id": 39,
            "product_id": 49,
            "product_code": "",
            "size_id": 14,
            "quantity": 3,
            "product": {
                "id": 49,
                "code": "",
                "factory_id": 2,
                "product_category_id": 1,
                "sex_id": null,
                "season_id": null,
                "product_type_id": null,
                "type_id": null,
                "color_id": null,
                "year_id": null,
                "image_1": "bceef8b28ae2a1797ca0c6300021100d.jpeg",
                "image_2": "",
                "image_3": "",
                "notes": "",
                "status": 10
            }
        },
        {
            "id": 137,
            "order_id": 39,
            "product_id": 48,
            "product_code": "",
            "size_id": null,
            "quantity": 24,
            "product": {
                "id": 48,
                "code": "",
                "factory_id": 2,
                "product_category_id": null,
                "sex_id": null,
                "season_id": null,
                "product_type_id": null,
                "type_id": null,
                "color_id": null,
                "year_id": null,
                "image_1": "2aee8660b4218bf549c2d9345beb2a01.jpeg",
                "image_2": "",
                "image_3": "",
                "notes": "",
                "status": 10
            }
        }]

Элементы, которые мне нужно проанализировать: product_id, size_id и quantity.Для этого я создал следующую структуру:

struct Products {
    let id: String
    let quantities: [(sizeId: String, quantity: String)]?

    init(id: String, quantities: [(sizeId: String, quantity: String)]) {
        self.id = id
        self.quantities = quantities
    }
}

Конечный результат, которого я пытаюсь достичь:

[Products(id: "49", quantities: [(sizeId: "13", quantity: "2"), (sizeId: "14", quantity: "3")]), 
Products(id: "48", quantities: [(sizeId: "null", quantity: "24")])]

При синтаксическом анализе с использованием SwiftyJSON я делаю это:

for productId in products.arrayValue {
                        self.productWithQuantites.append(Products(id: productId["product_id"].stringValue,
                                                                  quantities: [(sizeId: productId["size_id"].stringValue,
                                                                                quantity: productId["quantity"].stringValue)]))

                    }

Но я понимаю:

    [Products(id: "49", quantities: [(sizeId: "13", quantity: "2")]),
Products(id: "49", quantities: [(sizeId: "14", quantity: "3")],
Products(id: "48", quantities: [(sizeId: "null", quantity: "24")])]

Что я делаю не так?Как я могу добавить новые количества к моим существующим элементам?Был бы благодарен за пример кода или любую помощь.

Ответы [ 4 ]

0 голосов
/ 16 октября 2018

Вы должны использовать Alamofire с JSONDecoder вместо swiftyjson. Более подробную информацию вы можете посмотреть в этом видео, которое доступно по этой ссылке https://m.youtube.com/watch?v=YY3bTxgxWss

0 голосов
/ 16 октября 2018

Для более легкой модификации в таких циклах, вы должны сделать Products классом, так как он передается по ссылке.Кроме того, введите quantities в var в вашем Products и замените код синтаксического анализа на следующий:

for product in products.arrayValue {
    let productId = product["product_id"].stringValue

    let quantity = (sizeId: product["size_id"].stringValue,
                    quantity: product["quantity"].stringValue)

    if let product = self.productWithQuantites.filter({ $0.id == productId }).first {
        product.quantities?.append(quantity)
    } else {
        self.productWithQuantites.append(Products(id: productId, quantities: [quantity]))
    }
}

Этот код добавляет новый кортеж к свойству quantities существующего продукта,или, если он не существует, он создает новый Products и добавляет его к productWithQuantites.

0 голосов
/ 16 октября 2018

В Swift 4 SwiftyJSON устарел в пользу протокола Codable.

Не используйте кортежи в структурах, разделяйте значения и группируйте экземпляры Product (предпочтительна в единственном числе)в словарь в зависимости от идентификатора продукта.

Предполагая, что data содержит необработанные данные JSON, создайте эти крошечные структуры

struct Root : Decodable {
    let orderProducts : [Product]
}

struct Product: Decodable {
    let id : Int
    let productId : Int
    let sizeId : Int?
}

Декодируйте JSON в структуры и сгруппируйте массив с помощью Dictionary(grouping:by:)

do {
   let decoder = JSONDecoder()
   decoder.keyDecodingStrategy = .convertFromSnakeCase
   let result = try decoder.decode(Root.self, from: data)
   let groupedDictionary = Dictionary(grouping: result.orderProducts, by: {$0.productId})
   print(groupedDictionary)
   // [49: [Product(id: 135, productId: 49, sizeId: Optional(13)), 
   //      Product(id: 136, productId: 49, sizeId: Optional(14))], 
   //  48: [Product(id: 137, productId: 48, sizeId: nil)]]

} catch { print(error) }
0 голосов
/ 16 октября 2018

Это нормально получать, так как в вашем JSON есть две записи, с "product_id": 49

Таким образом, вы можете решить это как, после анализа вашего json, имея два цикла for для удаления, как только вынайти один и тот же предмет более одного раза, как указано ниже:

for i in 0..<productWithQuantites.count {
        for j in 0..<productWithQuantites.count {
            if productWithQuantites[i].productID == productWithQuantites[j].productID {
                productWithQuantites.remove(at: j)
            }
        }
    }
...