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
- true detective
- 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.