英文:
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。
英文:
I need to iterate over all the answer options from a json file:
{"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
}]}
]}
and write the paths and number, like:
{"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"}]
]}}
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:
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"`
}
)
And try to iterate:
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
}
But I don't understand how to correctly write recursive func and output struct for json.
答案1
得分: 0
由于您想创建多个路径,所以需要使用[][]Question
。
此外,您需要将递归函数的结果附加到返回值中,而不仅仅是返回结果。
以下是一个可行的示例:
func (input Input) Script(id int) (out [][]Question) {
for _, q := range input.Questions {
if q.Id == id {
added := false // 避免最后多次添加
for _, answer := range q.Answer {
paths := input.Script(answer.NextQuestion)
if len(paths) == 0 && !added {
// 答案没有下一个问题 | 输入中找不到问题
out = append(out, []Question{q})
added = true
}
for _, path := range paths {
// 在递归函数的每个路径前添加问题
path = append([]Question{q}, path...)
out = append(out, path)
}
}
return out
}
}
return out
}
希望对您有所帮助!
英文:
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:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论