Home > Software engineering >  how do I create array of strings from dictionary in swift?
how do I create array of strings from dictionary in swift?

Time:07-28

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.

CodePudding user response:

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)")
  • Related