在Go语言中递归迭代结构体数组。

huangapple go评论152阅读模式
英文:

recursively iterate struct array in Go

问题

我需要遍历一个JSON文件中的所有答案选项:

  1. {
  2. "questions": [
  3. {
  4. "id": 1,
  5. "question": "What is your marital status?",
  6. "answer": [
  7. {
  8. "text": "Single",
  9. "next_question": 2
  10. },
  11. {
  12. "text": "Married",
  13. "next_question": 3
  14. }
  15. ]
  16. },
  17. {
  18. "id": 2,
  19. "question": "Are you planning on getting married next year?",
  20. "answer": [
  21. {
  22. "text": "Yes",
  23. "next_question": 3
  24. },
  25. {
  26. "text": "No",
  27. "next_question": 5
  28. }
  29. ]
  30. },
  31. {
  32. "id": 3,
  33. "question": "How long have you been married?",
  34. "answer": [
  35. {
  36. "text": "Less than a year",
  37. "next_question": 6
  38. },
  39. {
  40. "text": "More than a year",
  41. "next_question": 4
  42. }
  43. ]
  44. },
  45. {
  46. "id": 4,
  47. "question": "Have you celebrated your one year anniversary?",
  48. "answer": [
  49. {
  50. "text": "Yes",
  51. "next_question": 7
  52. },
  53. {
  54. "text": "No",
  55. "next_question": 8
  56. }
  57. ]
  58. }
  59. ]
  60. }

并将路径和编号写入,例如:

  1. {
  2. "paths": {
  3. "number": 3,
  4. "list": [
  5. [
  6. {
  7. "What is your marital status?": "Single"
  8. },
  9. {
  10. "Are you planning on getting married next year?": "Yes/No"
  11. }
  12. ],
  13. [
  14. {
  15. "What is your marital status?": "Married"
  16. },
  17. {
  18. "How long have you been married?": "Less than a year"
  19. }
  20. ],
  21. [
  22. {
  23. "What is your marital status?": "Married"
  24. },
  25. {
  26. "How long have you been married?": "More than a year"
  27. },
  28. {
  29. "Have you celebrated your one year anniversary?": "Yes/No"
  30. }
  31. ]
  32. ]
  33. }
  34. }

你可以根据需要更改JSON结构,但主要是显示所有可能的调查路径数量(paths.number),以及按问题序列和答案显示的所有可能路径(paths.list)。

所以,我将JSON解析为以下结构:

  1. type (
  2. Answer struct {
  3. Text string `json:"text"`
  4. NextQuestion int `json:"next_question"`
  5. }
  6. Question struct {
  7. Id int `json:"id"`
  8. Question string `json:"question"`
  9. Answer []Answer `json:"answer"`
  10. }
  11. Input struct {
  12. Questions []Question `json:"questions"`
  13. }
  14. )

然后尝试进行迭代:

  1. func (input Input) Script(itterQuestion []Question, element Question) []Question {
  2. itterQuestion = append(itterQuestion, element)
  3. for i, item := range input.Questions {
  4. if item.Id != itterQuestion[i].Id {
  5. itterQuestion = append(itterQuestion, item)
  6. } else {
  7. return input.Script(itterQuestion, item)
  8. }
  9. }
  10. return itterQuestion
  11. }

但我不明白如何正确编写递归函数和输出结构以生成JSON。

英文:

I need to iterate over all the answer options from a json file:

  1. {"questions": [
  2. {"id": 1,
  3. "question": "What is your marital status?",
  4. "answer":[ {
  5. "text": "Single",
  6. "next_question": 2
  7. },
  8. {
  9. "text": "Married",
  10. "next_question": 3
  11. }]
  12. },
  13. {"id":2,
  14. "question": "Are you planning on getting married next year?",
  15. "answer":[{
  16. "text": "Yes",
  17. "next_question": 3
  18. },
  19. {
  20. "text": "No",
  21. "next_question": 5
  22. }]},
  23. {"id":3,
  24. "question": "How long have you been married?",
  25. "answer": [{
  26. "text": "Less than a year",
  27. "next_question": 6
  28. },
  29. {
  30. "text": "More than a year",
  31. "next_question": 4
  32. }]},
  33. {"id":4,
  34. "question":"Have you celebrated your one year anniversary?",
  35. "answer": [{
  36. "text": "Yes",
  37. "next_question": 7
  38. },
  39. {
  40. "text": "No",
  41. "next_question": 8
  42. }]}
  43. ]}

and write the paths and number, like:

  1. {"paths": {"number": 3, "list": [
  2. [{"What is your marital status?": "Single"},
  3. {"Are you planning on getting married next year?": "Yes/No"}],
  4. [{"What is your marital status?": "Married"},
  5. {"How long have you been married?": "Less than a year"}],
  6. [{"What is your marital status?": "Married"},
  7. {"How long have you been married?": "More than a year"},
  8. {"Have you celebrated your one year anniversary?": "Yes/No"}]
  9. ]}}

You can change JSON structure like you want, but the main thing is to display information about the number of all possible poll paths (paths.number), and all possible paths by a sequence of questions with answers (paths.list)

So, I parse JSON into this structs:

  1. type (
  2. Answer struct {
  3. Text string `json:"text"`
  4. NextQuestion int `json:"next_question"`
  5. }
  6. Question struct {
  7. Id int `json:"id"`
  8. Question string `json:"question"`
  9. Answer []Answer `json:"answer"`
  10. }
  11. Input struct {
  12. Questions []Question `json:"questions"`
  13. }
  14. )

And try to iterate:

  1. func (input Input) Script(itterQuestion []Question, element Question) []Question {
  2. itterQuestion = append(itterQuestion, element)
  3. for i, item := range input.Questions {
  4. if item.Id != itterQuestion[i].Id {
  5. itterQuestion = append(itterQuestion, item)
  6. } else {
  7. return input.Script(itterQuestion, item)
  8. }
  9. }
  10. return itterQuestion
  11. }

But I don't understand how to correctly write recursive func and output struct for json.

答案1

得分: 0

由于您想创建多个路径,所以需要使用[][]Question
此外,您需要将递归函数的结果附加到返回值中,而不仅仅是返回结果。

以下是一个可行的示例:

  1. func (input Input) Script(id int) (out [][]Question) {
  2. for _, q := range input.Questions {
  3. if q.Id == id {
  4. added := false // 避免最后多次添加
  5. for _, answer := range q.Answer {
  6. paths := input.Script(answer.NextQuestion)
  7. if len(paths) == 0 && !added {
  8. // 答案没有下一个问题 | 输入中找不到问题
  9. out = append(out, []Question{q})
  10. added = true
  11. }
  12. for _, path := range paths {
  13. // 在递归函数的每个路径前添加问题
  14. path = append([]Question{q}, path...)
  15. out = append(out, path)
  16. }
  17. }
  18. return out
  19. }
  20. }
  21. return out
  22. }

希望对您有所帮助!

英文:

Since you want to create multiple paths there is gotta be [][]Question.
Also you have to append result from recursive function instead just returning.

Here's working example:

  1. func (input Input) Script (id int) (out [][]Question) {
  2. for _, q := range input.Questions {
  3. if q.Id == id {
  4. added := false // avoid add last multiple times
  5. for _, answer := range q.Answer {
  6. paths := input.Script(answer.NextQuestion)
  7. if len(paths) == 0 && !added {
  8. // answer has no next question | question not found in input
  9. out = append(out, []Question{q})
  10. added = true
  11. }
  12. for _, path := range paths {
  13. // prepend question to every path from recursive function
  14. path = append([]Question{q}, path...)
  15. out = append(out, path)
  16. }
  17. }
  18. return out
  19. }
  20. }
  21. return out
  22. }

huangapple
  • 本文由 发表于 2022年3月25日 22:38:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/71618744.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定