Home > Enterprise >  how to populate array of dictionary values to tableview?-swift
how to populate array of dictionary values to tableview?-swift

Time:05-20

I have a multidimensional array

var sectionArray = [ ["sectionName":"Time","sectionData":[["fname":"true detective","date":"may 20"],["fname":"abbas","date":"may 10"]],"expanaded":false],["sectionName":"Message","sectionData":[["movie":"true","event":"Bring food"]]

from this array I have to get fname keys value where fname is the value of the key sectionData.how will I achieve that? I have to populate this data on tableview my cellForRowAt

switch (indexPath.section) {
    case 0:
        if let cell1 = tableview.dequeueReusableCell(withIdentifier: "DetailedTableViewCell", for: indexPath) as? DetailedTableViewCell{
            let c = indexPath.section
            cell1.timeCardTitle.text = sectionArray[c]["sectionName"][c]["fname"] as? String
            
        return cell1
        }

CodePudding user response:

   var fNames:[String] = [] {
    didSet {
        tableView.reloadData()
      }
   }

   var sectionArray = [["sectionName":"Time","sectionData":[["fname":"true detective","date":"may 20"],["fname":"abbas","date":"may 10"]],"expanaded":false],["sectionName":"Message","sectionData":[["movie":"true","event":"Bring food"]]]]



fileprivate func gettingFNames() {
        sectionArray.forEach { value in
            let sectionData = value["sectionData"] as? [[String:Any]]
            sectionData?.forEach({ section in
                if let fname = section["fname"] as? String {
                    fNames.append(fname)
                    print(fname)
                }
            })
        }
    }

    

the array will be

  1. true detective
  2. abbas

CodePudding user response:

It's easier if you make structured data from your unstructured dictionary representation:

var sectionArray = [ ["sectionName":"Time",
                      "sectionData":[["fname":"true detective","date":"may 20"],["fname":"abbas","date":"may 10"]],
                      "expanaded":false],
                     ["sectionName":"Message","sectionData":[["movie":"true","event":"Bring food"]]]]

struct Row {
    var fname: String
    var date: String
}
struct Section {
    var name: String
    var rows: [Row]
    var expanded: Bool
}

var arranged: [Section] = sectionArray.compactMap { s in
    guard let name = s["sectionName"] as? String,
          let sectionData = s["sectionData"] as? [[String:Any]] else {
        return nil
    }

    let isExpanded = s["expanaded"] as? Bool ?? false

    let rows = sectionData.compactMap { rd -> Row? in
        guard let fname = rd["fname"] as? String,
              let date = rd["date"] as? String else {
                  return nil
              }

        return Row(fname: fname, date: date)
    }

    return .init(name: name, rows: rows, expanded: isExpanded)
}

Now you can implement the table view data source's number of sections as arranged.count, and number of rows in sections as arranged[indexPath.section].count and configure your cell for any particular row by getting the row model using arranged[indexPath.section].rows[indexPath.row] and then using it to configure a cell.

Actually I notice you have two types of rows, so things will be much easier if you can get your data in this form:

enum Row {
    case type1(fname: String, date: String)
    case type2(movie: String, event: String)
}

struct Section {
    var name: String
    var rows: [Row]
    var expanded: Bool
}

var arranged: [Section] = [
    Section(name: "Time", rows: [
        Row.type1(fname: "true detective", date: "may 20"),
        Row.type1(fname: "abbas", date: "may 10")
    ], expanded: false),
    Section(name: "Message", rows: [
        Row.type2(movie: "true", event: "Bring food")
        ], expanded: true)
]

When making a cell for cellForRowAtIndexPath, you can switch on the row type and then dequeue and configure reusable cell for the correct type.

  • Related