首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数组中的嵌套字典键值在swift 4中使用codable

数组中的嵌套字典键值在swift 4中使用codable
EN

Stack Overflow用户
提问于 2020-05-15 15:31:21
回答 2查看 133关注 0票数 0

我在下面的结构中有json。

代码语言:javascript
复制
{
    "message": null,
    "data": {
        "admin": {
            "UserId": 1,
            "CUSTOMER_PROFILING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "RISK_ASSESSMENT": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "LINK_ANALYSIS": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "BENCH_MARKING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "SUSPICIOUS_TRANSACTION_REPORTING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "THRESHOLD_TRANSACTION_REPORTING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            }
        },
        "vinoth59": {
            "UserId": 15,
            "CUSTOMER_PROFILING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "RISK_ASSESSMENT": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "LINK_ANALYSIS": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "BENCH_MARKING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "SUSPICIOUS_TRANSACTION_REPORTING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "THRESHOLD_TRANSACTION_REPORTING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            }
        },
        "ba_user": {
            "UserId": 16,
            "CUSTOMER_PROFILING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "RISK_ASSESSMENT": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "LINK_ANALYSIS": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "BENCH_MARKING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "SUSPICIOUS_TRANSACTION_REPORTING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            },
            "THRESHOLD_TRANSACTION_REPORTING": {
                "id": 0,
                "total": 0,
                "high": 0,
                "low": 0,
                "medium": 0
            }
        }
    },
    "status": true
}

我的可编码类如下所示

代码语言:javascript
复制
struct UserRiskReportBase : Codable {
    let message : String?
    let data : [String:UserRiskReport]?
    let status : Bool?

    enum CodingKeys: String, CodingKey {

        case message = "message"
        case data = "data"
        case status = "status"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        message = try values.decodeIfPresent(String.self, forKey: .message)
        data = try values.decodeIfPresent([String:[String:BenchMarking]].self, forKey: .data)
        status = try values.decodeIfPresent(Bool.self, forKey: .status)
    }

}
struct UserRiskReport: Codable {
    let userID: Int
    let customerProfiling, riskAssessment, linkAnalysis, benchMarking: BenchMarking
    let suspiciousTransactionReporting, thresholdTransactionReporting: BenchMarking

    enum CodingKeys: String, CodingKey {
        case userID = "UserId"
        case customerProfiling = "CUSTOMER_PROFILING"
        case riskAssessment = "RISK_ASSESSMENT"
        case linkAnalysis = "LINK_ANALYSIS"
        case benchMarking = "BENCH_MARKING"
        case suspiciousTransactionReporting = "SUSPICIOUS_TRANSACTION_REPORTING"
        case thresholdTransactionReporting = "THRESHOLD_TRANSACTION_REPORTING"
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        userID = try values.decodeIfPresent(Int.self, forKey: .userID)!
        customerProfiling = try values.decodeIfPresent(BenchMarking.self, forKey: .customerProfiling)!
        benchMarking = try values.decodeIfPresent(BenchMarking.self, forKey: .benchMarking)!
        riskAssessment = try values.decodeIfPresent(BenchMarking.self, forKey: .riskAssessment)!
        suspiciousTransactionReporting = try values.decodeIfPresent(BenchMarking.self, forKey: .suspiciousTransactionReporting)!
        linkAnalysis = try values.decodeIfPresent(BenchMarking.self, forKey: .linkAnalysis)!
        thresholdTransactionReporting = try values.decodeIfPresent(BenchMarking.self, forKey: .thresholdTransactionReporting)!

    }
}

struct BenchMarking : Codable {
    let id : Int?
    let total : Int?
    let high : Int?
    let low : Int?
    let medium : Int?

    enum CodingKeys: String, CodingKey {

        case id = "id"
        case total = "total"
        case high = "high"
        case low = "low"
        case medium = "medium"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decodeIfPresent(Int.self, forKey: .id)
        total = try values.decodeIfPresent(Int.self, forKey: .total)
        high = try values.decodeIfPresent(Int.self, forKey: .high)
        low = try values.decodeIfPresent(Int.self, forKey: .low)
        medium = try values.decodeIfPresent(Int.self, forKey: .medium)
    }
}

我能拿到第一级密钥

代码语言:javascript
复制
let dec = JSONDecoder()
                    dec.keyDecodingStrategy = .convertFromSnakeCase
                    let alertList = try dec.decode(UserRiskReportBase.self, from:response.data!)

                    self.userRiskReportList = alertList.data!
                    self.headerArr = Array(alertList.data!.keys)

                    print(self.headerArr)

我得到了像"admin","vinoth59","ba_user“这样的第一级键。我需要得到二级密钥"CUSTOMER_PROFILING","RISK_ASSESSMENT",......如何使用此可编码性来实现

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-15 16:33:18

下面的代码适用于我,请注意,我做了一些简化并删除了不需要的代码,如init(from:),我还删除了许多属性的可选代码

代码语言:javascript
复制
struct UserRiskReportBase : Codable {
    let message : String?
    let data : [String:UserRiskReport]
    let status : Bool?
}

struct UserRiskReport: Codable {
    let userID: Int
    let customerProfiling, riskAssessment, linkAnalysis, benchMarking: BenchMarking
    let suspiciousTransactionReporting, thresholdTransactionReporting: BenchMarking

    enum CodingKeys: String, CodingKey, CaseIterable {
        case userID = "UserId"
        case customerProfiling = "CUSTOMER_PROFILING"
        case riskAssessment = "RISK_ASSESSMENT"
        case linkAnalysis = "LINK_ANALYSIS"
        case benchMarking = "BENCH_MARKING"
        case suspiciousTransactionReporting = "SUSPICIOUS_TRANSACTION_REPORTING"
        case thresholdTransactionReporting = "THRESHOLD_TRANSACTION_REPORTING"
    }

    var allKeys: [String] {
        get {
            CodingKeys.allCases.map {$0.rawValue}
        }
    }
}

struct BenchMarking : Codable {
    let id : Int
    let total : Int
    let high : Int
    let low : Int
    let medium : Int
}

do {
    let result = try JSONDecoder().decode(UserRiskReportBase.self, from: data)
    for item in result.data.values {
        print("Report for user: \(item.userID)")
        print(item.customerProfiling)
        print(item.benchMarking)
        //print(...)
    }
} catch {
    print(error)
}
票数 1
EN

Stack Overflow用户

发布于 2020-05-15 16:46:45

代码语言:javascript
复制
    let dec = JSONDecoder()
    dec.keyDecodingStrategy = .useDefaultKeys
    let alertList = try? dec.decode(UserRiskReportBase.self, from: respData!)
    print("Compelete Data: ", alertList)

    let baUser = alertList?.data["ba_user"] as? UserRiskReport
    print("ba_user", alertList?.data["ba_user"])
    print(baUser?.benchMarking.id)
    print(baUser?.thresholdTransactionReporting.total)

记住用.useDefaultKeys替换.convertFromSnakeCase

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61814001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档