简体   繁体   中英

how do I create array of strings from dictionary in swift?

So basically below I have Json in which I have two parameters dimensions (dictionary) and measures (array of string) which I need to parse.

{"Dimensions":[{"Channel":"VARCHAR"},{"Indication":"VARCHAR"},{"LOT":"VARCHAR"},{"Monthly":"DATE"},{"Yearly":"VARCHAR"},{"Quarterly":"DATE"},{"Parameter_Classification":"VARCHAR"},{"Parameter_Type_1":"VARCHAR"},{"Parameter_Type_2":"VARCHAR"},{"Parameter_Type_3":"VARCHAR"},{"Payer_Type":"VARCHAR"},{"Product":"VARCHAR"},{"Project_Name":"VARCHAR"},{"Regime":"VARCHAR"},{"Region":"VARCHAR"},{"Scenario":"VARCHAR"},{"Trial_Name":"VARCHAR"}],"Measures":["ANSP","ASP","Demand units","DOH","EPI","Ex Factory","Gross sales","Inventory Units","Market Share","Net sales","NPS PAP","Patients","Revenue","TRx","Units","WAC"]}

Model from this json

struct Welcome: Codable {
    let dimensions: [Dimension]
    let measures: [String]

    enum CodingKeys: String, CodingKey {
        case dimensions = "Dimensions"
        case measures = "Measures"
    }
}

struct Dimension: Codable {
    let channel, indication, lot, monthly: String?
    let yearly, quarterly, parameterClassification, parameterType1: String?
    let parameterType2, parameterType3, payerType, product: String?
    let projectName, regime, region, scenario: String?
    let trialName: String?

    enum CodingKeys: String, CodingKey {
        case channel = "Channel"
        case indication = "Indication"
        case lot = "LOT"
        case monthly = "Monthly"
        case yearly = "Yearly"
        case quarterly = "Quarterly"
        case parameterClassification = "Parameter_Classification"
        case parameterType1 = "Parameter_Type_1"
        case parameterType2 = "Parameter_Type_2"
        case parameterType3 = "Parameter_Type_3"
        case payerType = "Payer_Type"
        case product = "Product"
        case projectName = "Project_Name"
        case regime = "Regime"
        case region = "Region"
        case scenario = "Scenario"
        case trialName = "Trial_Name"
    }
}

I basically need to parse this json and have all the keys in dimensions as an array of strings exactly like I have of measures how do I do that while I parse json?

private func decodeJson(welcomeString: String) {
    let data = Data(welcomeString.utf8)
    do {
        let infoType = try JSONDecoder().decode(Welcome.self, from: data)
//        print(infoType.dimensions)
//        print(infoType.measures)
    } catch let error {
        print(error)
    }
}

welcomeString is json in the form of Json. thanks.

try this approach as shown in this example SwiftUI code, to "...have all the keys in dimensions as an array of strings..", works for me:

struct ContentView: View {
    @State var items = [[String:String]]()
    
    var body: some View {
        List (items, id: \.self) { item in
            ForEach([String](item.keys), id: \.self) { key in
                Text(key + " " + (item[key] ?? ""))
            }
        }
        .onAppear {
            let welcomeString = """
{"Dimensions":[{"Channel":"VARCHAR"},{"Indication":"VARCHAR"},{"LOT":"VARCHAR"},{"Monthly":"DATE"},{"Yearly":"VARCHAR"},{"Quarterly":"DATE"},{"Parameter_Classification":"VARCHAR"},{"Parameter_Type_1":"VARCHAR"},{"Parameter_Type_2":"VARCHAR"},{"Parameter_Type_3":"VARCHAR"},{"Payer_Type":"VARCHAR"},{"Product":"VARCHAR"},{"Project_Name":"VARCHAR"},{"Regime":"VARCHAR"},{"Region":"VARCHAR"},{"Scenario":"VARCHAR"},{"Trial_Name":"VARCHAR"}],"Measures":["ANSP","ASP","Demand units","DOH","EPI","Ex Factory","Gross sales","Inventory Units","Market Share","Net sales","NPS PAP","Patients","Revenue","TRx","Units","WAC"]}
"""
            
            let data = Data(welcomeString.utf8)
            do {
                let results = try JSONDecoder().decode(Welcome.self, from: data)
                //    print("\n---> results: \(results)")
                items = results.dimensions
                //    print("\n---> items: \(items)")

                let allkeys = results.dimensions.compactMap{$0.first?.key}
                print("\n---> allkeys: \(allkeys)")

            } catch (let error) {
                print("\n---> error: \(error)")
            }
            
        }
    }
    
}

struct Welcome: Codable {
    let dimensions: [[String:String]]
    let measures: [String]
    
    enum CodingKeys: String, CodingKey {
        case dimensions = "Dimensions"
        case measures = "Measures"
    }
}

To get just the keys, try this (see also.onAppear):

    let allkeys = items.compactMap{$0.first?.key}
    print("\n---> allkeys: \(allkeys)")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM