使用嵌套数组,在到达第一个嵌套数组结束元素的末尾后访问下一个数组

问题描述 投票:0回答:1

我想访问此 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()

}

如何转到数组的下一个索引?

swift multidimensional-array tree
1个回答
0
投票

请检查https://github.com/immanaro2497/MovieQuestions。我已经创建了一个示例。

我已将每个树项目更改为只有问题和选择。选项中的问题将创建为新的树项目。

originalQuestions 变量用于获取原始数据,无需任何用户更改。

questionsWithAnswer 变量是带有用户交互数据的问题列表。如果需要,您可以添加新属性。该列表将根据所选选项和其他用户交互进行更新(当前仅针对选项选择实现)。

© www.soinside.com 2019 - 2024. All rights reserved.