我想访问此 JSON 的元素:
{
"status" : true,
"code" : 200,
"results" : [
{
"choice" : null,
"assessment" : 133,
"id" : 863,
"title" : "What do you like to eat duing a movie?",
"choices" : [
{
"id" : 1738,
"title" : "Popcorn",
"nas_class" : "c1",
"question" : 863,
"questions" : [
{
"choice" : 1738,
"assessment" : 133,
"id" : 864,
"title" : "What flavours of popcorn do you like?",
"choices" : [
{
"id" : 1739,
"title" : "Caramel",
"nas_class" : "c1",
"question" : 864,
"questions" : [
]
},
{
"id" : 1740,
"title" : "Cheese",
"nas_class" : "c1",
"question" : 864,
"questions" : [
]
},
{
"id" : 1741,
"title" : "Tomato",
"nas_class" : "c1",
"question" : 864,
"questions" : [
]
},
{
"id" : 1742,
"title" : "Chilli",
"nas_class" : "c1",
"question" : 864,
"questions" : [
{
"choice" : 1742,
"assessment" : 133,
"id" : 865,
"title" : "How good is your spice tolerance?",
"choices" : [
],
"description" : "",
"type" : "rating",
"creator" : 5
}
]
}
],
"description" : "",
"type" : "multi_select",
"creator" : 5
}
]
},
{
"id" : 1743,
"title" : "Nachos",
"nas_class" : "c1",
"question" : 863,
"questions" : [
]
},
{
"id" : 1744,
"title" : "Chips",
"nas_class" : "c1",
"question" : 863,
"questions" : [
]
}
],
"description" : "",
"type" : "single_select",
"creator" : 5
},
{
"choice" : null,
"assessment" : 133,
"id" : 866,
"title" : "Describe the kind of stories you enjoy watching",
"choices" : [
],
"description" : "",
"type" : "free_text",
"creator" : 5
},
{
"choice" : null,
"assessment" : 133,
"id" : 867,
"title" : "Sign here to indicate that you consent selling of your data",
"choices" : [
],
"description" : "",
"type" : "signature",
"creator" : 5
},
{
"choice" : null,
"assessment" : 133,
"id" : 868,
"title" : "Upload a picture of your driving license",
"choices" : [
],
"description" : "",
"type" : "file_upload",
"creator" : 5
},
{
"choice" : null,
"assessment" : 133,
"id" : 869,
"title" : "Give your opinion",
"choices" : [
{
"id" : 1745,
"title" : "Bad",
"nas_class" : "c1",
"question" : 869,
"questions" : [
]
},
{
"id" : 1746,
"title" : "Poor",
"nas_class" : "c1",
"question" : 869,
"questions" : [
]
},
{
"id" : 1747,
"title" : "Good",
"nas_class" : "c1",
"question" : 869,
"questions" : [
]
},
{
"id" : 1748,
"title" : "Excellent",
"nas_class" : "c1",
"question" : 869,
"questions" : [
]
}
],
"description" : "",
"type" : "single_select",
"creator" : 5
}
],
"msg" : "Success"
}
我能够访问索引 0 处的第一个数组,并且可以到达嵌套数组的末尾,但在到达 n 个数组元素的末尾后需要转移到索引 1 等。我该如何实现它?我也已将结构添加到问题中。
// MARK: - TreeItem
struct TreeItem {
var id: Int
var title: String
var description: String
var type: String
var assessment: Int
var choices: [ChoiceItem]?
var choice: Int?
var creator: Int
var isSelected : String?
}
// MARK: - ChoiceItem
struct ChoiceItem {
var id: Int
var title: String
var nasClass: String
var question: Int
var questions: [TreeItem]?
}
使用此函数将 n 数组树转换为嵌套数组。我是嵌套数组的新手。
// Fetching json from api and storing it in the structs
func fetchData() {
showLoader()
AssessmentQuestionsViewModel.getAssessmentQuestions(for: assessmentID) { result in
self.hideLoader()
switch result {
case .Success(let questions):
self.objResponseQuestions = questions.results
self.arrayObjResultQuestionsCount = (self.objResponseQuestions?.count ?? 0)
if let assesmentDataValue = self.objResponseQuestions {
self.treeArray = self.convertTreeToArray(assesmentDataValue)
self.setData()
}
self.tableView.reloadData()
case.CustomError(let errorMessage):
self.view.showTost("The Assessment Details are not available at the moment")
}
}
}
// function used to convert the nested n array tree to a array of struct TreeItem
func convertTreeToArray(_ roots: [ResultsQuestions]?) -> [TreeItem] {
guard let roots = roots else {
return []
}
var result: [TreeItem] = []
for root in roots {
result.append(contentsOf: convertNodeToArray(root))
}
// print(result)
return result
}
func convertNodeToArray(_ node: ResultsQuestions) -> [TreeItem] {
var result: [TreeItem] = [TreeItem(id: node.id,
title: node.title,
description: node.description,
type: node.type,
assessment: node.assessment,
choices: convertChoices(node.choices),
choice: node.choice,
creator: node.creator ?? 0,
isSelected: nil)]
if let choices = node.choices {
for choice in choices {
if let questions = choice.questions {
result += questions.flatMap { convertNodeToArray($0) }
}
}
}
return result
}
func convertChoices(_ choices: [Choice]?) -> [ChoiceItem]? {
guard let choices = choices else {
return nil
}
return choices.map { choice in
return ChoiceItem(id: choice.id,
title: choice.title,
nasClass: choice.nasClass,
question: choice.question,
questions: choice.questions?.flatMap { convertNodeToArray($0) })
}
}
// As mention in the comments about another link. The UI screenshot is present there.
// Next button for getting the next array index
@IBAction func nextScreenButtonActions(_ sender: UIButton) {
if isNextQuestionAvailable == true {
firstTreeArray?.choices?.removeAll()
firstTreeArray?.type.removeAll()
firstTreeArray?.choices?.removeAll()
firstTreeArray = newChoiceItemSelected?.questions?.first
self.questionLabel.text = firstTreeArray?.title ?? ""
self.tempQuestionNumber = self.tempQuestionNumber + 1
self.questionNumberLabel.text = "Q" + " " + String(describing: self.tempQuestionNumber)
tableView.reloadData()
} else {
//All Next choices in the array depth are nil as they should move to another array
firstTreeArray?.choices?.removeAll()
firstTreeArray?.type.removeAll()
firstTreeArray?.choices?.removeAll()
self.firstTreeArray = self.treeArray[newIndexForTreeArray]
self.questionLabel.text = firstTreeArray?.title ?? ""
tableView.reloadData()
if arrayObjResultQuestionsCount >= newIndexForTreeArray {
newIndexForTreeArray += 1
self.tempQuestionNumber = self.tempQuestionNumber + 1
self.questionNumberLabel.text = "Q" + " " + String(describing: self.tempQuestionNumber)
} else if arrayObjResultQuestionsCount == newIndexForTreeArray {
print("No increment in the value of the count. ")
self.tempQuestionNumber = arrayObjResultQuestionsCount
self.questionNumberLabel.text = "Q" + " " + String(describing: self.tempQuestionNumber)
} else if arrayObjResultQuestionsCount == 1 {
print("No increment in the value of the count. ")
self.tempQuestionNumber = arrayObjResultQuestionsCount
self.questionNumberLabel.text = "Q" + " " + String(describing: self.tempQuestionNumber)
}
}
}
// UITableView cell for row at function , using closure to check if the nested array is empty or no.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var AssessmentDataTypes = firstTreeArray?.type
case "multi_select" :
guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: nestedAssessmentTableViewCell.self), for: indexPath) as? nestedAssessmentTableViewCell else { return nestedAssessmentTableViewCell() }
cell.selectionStyle = UITableViewCell.SelectionStyle.none
cell.optionsLabel.text = firstTreeArray?.choices?[indexPath.row].title
cell.optionsButton.setImage(UIImage(named: "TickUnselected"), for: .normal)
// self.nextScreenButton.isUserInteractionEnabled = true
cell.optionsButtonPressed = {[weak self ] in
guard let self = self else {return}
newChoiceItemSelected = firstTreeArray?.choices?[indexPath.row]
if newChoiceItemSelected?.questions?.isEmpty == true {
isNextQuestionAvailable = false
} else {
firstTreeArray?.isSelected = "True"
isNextQuestionAvailable = true
}
}
return cell
case "single_select":
guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: nestedAssessmentTableViewCell.self), for: indexPath) as? nestedAssessmentTableViewCell else { return nestedAssessmentTableViewCell() }
cell.selectionStyle = UITableViewCell.SelectionStyle.none
cell.optionsButton.setImage(UIImage(named: "TickUnselected"), for: .normal)
cell.optionsLabel.text = firstTreeArray?.choices?[indexPath.row].title
// self.nextScreenButton.isUserInteractionEnabled = true
cell.optionsButtonPressed = {[weak self ] in
guard let self = self else {return}
// print(indexPath.row)
newChoiceItemSelected = firstTreeArray?.choices?[indexPath.row]
if newChoiceItemSelected?.questions?.isEmpty == true {
isNextQuestionAvailable = false
} else if newChoiceItemSelected?.questions == nil {
isNextQuestionAvailable = false
} else {
firstTreeArray?.isSelected = "True"
isNextQuestionAvailable = true
}
}
return cell
default:
break
}
return UITableViewCell()
}
如何转到数组的下一个索引?
请检查https://github.com/immanaro2497/MovieQuestions。我已经创建了一个示例。
我已将每个树项目更改为只有问题和选择。选项中的问题将创建为新的树项目。
originalQuestions 变量用于获取原始数据,无需任何用户更改。
questionsWithAnswer 变量是带有用户交互数据的问题列表。如果需要,您可以添加新属性。该列表将根据所选选项和其他用户交互进行更新(当前仅针对选项选择实现)。