在 Go 中递归迭代结构数组
recursively iterate struct array in Go
我需要遍历 json 文件中的所有答案选项:
{"questions": [
{"id": 1,
"question": "What is your marital status?",
"answer":[ {
"text": "Single",
"next_question": 2
},
{
"text": "Married",
"next_question": 3
}]
},
{"id":2,
"question": "Are you planning on getting married next year?",
"answer":[{
"text": "Yes",
"next_question": 3
},
{
"text": "No",
"next_question": 5
}]},
{"id":3,
"question": "How long have you been married?",
"answer": [{
"text": "Less than a year",
"next_question": 6
},
{
"text": "More than a year",
"next_question": 4
}]},
{"id":4,
"question":"Have you celebrated your one year anniversary?",
"answer": [{
"text": "Yes",
"next_question": 7
},
{
"text": "No",
"next_question": 8
}]}
]}
并写下路径和编号,如:
{"paths": {"number": 3, "list": [
[{"What is your marital status?": "Single"},
{"Are you planning on getting married next year?": "Yes/No"}],
[{"What is your marital status?": "Married"},
{"How long have you been married?": "Less than a year"}],
[{"What is your marital status?": "Married"},
{"How long have you been married?": "More than a year"},
{"Have you celebrated your one year anniversary?": "Yes/No"}]
]}}
您可以根据需要更改 JSON 结构,但主要是显示有关所有可能的轮询路径 (paths.number) 数量的信息,以及所有可能的路径的序列有答案的问题 (paths.list)
所以,我将 JSON 解析为这个结构:
type (
Answer struct {
Text string `json:"text"`
NextQuestion int `json:"next_question"`
}
Question struct {
Id int `json:"id"`
Question string `json:"question"`
Answer []Answer `json:"answer"`
}
Input struct {
Questions []Question `json:"questions"`
}
)
并尝试迭代:
func (input Input) Script(itterQuestion []Question, element Question) []Question {
itterQuestion = append(itterQuestion, element)
for i, item := range input.Questions {
if item.Id != itterQuestion[i].Id {
itterQuestion = append(itterQuestion, item)
} else {
return input.Script(itterQuestion, item)
}
}
return itterQuestion
}
但我不明白如何正确编写 json 的递归函数和输出结构。
既然要创建多条路径,那肯定是[][]Question
。
此外,您还必须附加递归函数的结果,而不是直接返回。
这是工作示例:
func (input Input) Script (id int) (out [][]Question) {
for _, q := range input.Questions {
if q.Id == id {
added := false // avoid add last multiple times
for _, answer := range q.Answer {
paths := input.Script(answer.NextQuestion)
if len(paths) == 0 && !added {
// answer has no next question | question not found in input
out = append(out, []Question{q})
added = true
}
for _, path := range paths {
// prepend question to every path from recursive function
path = append([]Question{q}, path...)
out = append(out, path)
}
}
return out
}
}
return out
}
我需要遍历 json 文件中的所有答案选项:
{"questions": [
{"id": 1,
"question": "What is your marital status?",
"answer":[ {
"text": "Single",
"next_question": 2
},
{
"text": "Married",
"next_question": 3
}]
},
{"id":2,
"question": "Are you planning on getting married next year?",
"answer":[{
"text": "Yes",
"next_question": 3
},
{
"text": "No",
"next_question": 5
}]},
{"id":3,
"question": "How long have you been married?",
"answer": [{
"text": "Less than a year",
"next_question": 6
},
{
"text": "More than a year",
"next_question": 4
}]},
{"id":4,
"question":"Have you celebrated your one year anniversary?",
"answer": [{
"text": "Yes",
"next_question": 7
},
{
"text": "No",
"next_question": 8
}]}
]}
并写下路径和编号,如:
{"paths": {"number": 3, "list": [
[{"What is your marital status?": "Single"},
{"Are you planning on getting married next year?": "Yes/No"}],
[{"What is your marital status?": "Married"},
{"How long have you been married?": "Less than a year"}],
[{"What is your marital status?": "Married"},
{"How long have you been married?": "More than a year"},
{"Have you celebrated your one year anniversary?": "Yes/No"}]
]}}
您可以根据需要更改 JSON 结构,但主要是显示有关所有可能的轮询路径 (paths.number) 数量的信息,以及所有可能的路径的序列有答案的问题 (paths.list)
所以,我将 JSON 解析为这个结构:
type (
Answer struct {
Text string `json:"text"`
NextQuestion int `json:"next_question"`
}
Question struct {
Id int `json:"id"`
Question string `json:"question"`
Answer []Answer `json:"answer"`
}
Input struct {
Questions []Question `json:"questions"`
}
)
并尝试迭代:
func (input Input) Script(itterQuestion []Question, element Question) []Question {
itterQuestion = append(itterQuestion, element)
for i, item := range input.Questions {
if item.Id != itterQuestion[i].Id {
itterQuestion = append(itterQuestion, item)
} else {
return input.Script(itterQuestion, item)
}
}
return itterQuestion
}
但我不明白如何正确编写 json 的递归函数和输出结构。
既然要创建多条路径,那肯定是[][]Question
。
此外,您还必须附加递归函数的结果,而不是直接返回。
这是工作示例:
func (input Input) Script (id int) (out [][]Question) {
for _, q := range input.Questions {
if q.Id == id {
added := false // avoid add last multiple times
for _, answer := range q.Answer {
paths := input.Script(answer.NextQuestion)
if len(paths) == 0 && !added {
// answer has no next question | question not found in input
out = append(out, []Question{q})
added = true
}
for _, path := range paths {
// prepend question to every path from recursive function
path = append([]Question{q}, path...)
out = append(out, path)
}
}
return out
}
}
return out
}