I need to reshape a bit my data. Idea is that I have array of questions, each question has their index and option array. Inside option array there is answerLabel and optional linksTo. linksto shows which question should be next. In case of no linksTo, path is over in this spot. I need to loop through data as many times to get all possible paths. So overall my data looks more or less like this:
const mockData: Tree = {
name: "My tree",
description: "string",
questions: [
{
questionIdx: 1,
question: "Do you like potato",
description: "string",
options: [
{
answerIdx: 1,
answerLabel: "Yes",
linksTo: 2,
},
{
answerIdx: 2,
answerLabel: "No",
linksTo: 3,
},
],
},
{
questionIdx: 2,
question: "Do you like carrot",
description: "string",
options: [
{
answerIdx: 1,
answerLabel: "Yes",
linksTo: 3,
},
{
answerIdx: 2,
answerLabel: "No",
},
],
},
{
questionIdx: 3,
question: "Do you like anything",
description: "string",
options: [
{
answerIdx: 1,
answerLabel: "Yes",
},
{
answerIdx: 2,
answerLabel: "No",
},
],
},
],
};
and example above needs to get that kind of shape:
const mockedOutput: PathsData = {
name: "string",
paths: [
{
pathIdx: 1,
show: true,
path: [
{
questionIdx: 1,
question: "Do you like potato",
answerLabel: "Yes",
linksTo: 2,
},
{
questionIdx: 2,
question: "Do you like carrot",
answerLabel: "Yes",
linksTo: 3,
},
{
questionIdx: 3,
question: '"Do you like anything',
answerLabel: "Yes",
},
],
},
{
pathIdx: 2,
show: true,
path: [
{
questionIdx: 1,
question: "Do you like potato",
answerLabel: "Yes",
linksTo: 2,
},
{
questionIdx: 2,
question: "Do you like carrot",
answerLabel: "Yes",
linksTo: 3,
},
{
questionIdx: 3,
question: '"Do you like anything',
answerLabel: "No",
},
],
},
{
pathIdx: 3,
show: true,
path: [
{
questionIdx: 1,
question: "Do you like potato",
answerLabel: "No",
linksTo: 3,
},
{
questionIdx: 2,
question: "Do you like carrot",
answerLabel: "Yes",
linksTo: 3,
},
{
questionIdx: 3,
question: '"Do you like anything',
answerLabel: "Yes",
},
],
},
{
pathIdx: 4,
show: true,
path: [
{
questionIdx: 1,
question: "Do you like potato",
answerLabel: "No",
linksTo: 3,
},
{
questionIdx: 2,
question: "Do you like carrot",
answerLabel: "Yes",
linksTo: 3,
},
{
questionIdx: 3,
question: '"Do you like anything',
answerLabel: "No",
},
],
},
{
pathIdx: 5,
show: true,
path: [
{
questionIdx: 1,
question: "Do you like potato",
answerLabel: "Yes",
linksTo: 2,
},
{
questionIdx: 2,
question: "Do you like carrot",
answerLabel: "No",
},
],
},
],
};
I figured out that best for this case will be some recursive function which will loop over array of questions, create each path based on linksTo. In case multiple option (btw there can be more than just 2 options) it will start again and go with another options. Problem is I totally cannot figure out logic to write this function.
That’s what I got so far but I already see that probably I took wrong approach, also I cannot spot moment where to switch startAgain flag:
function aggregateData(
originalData: DecisionTree,
output: PathsData,
startAgain: boolean
) {
if (!startAgain) return output;
const result: PathsData = {
...output,
paths: originalData.questions.map((question, i) => {
const obj = {
pathIdx: i,
show: true,
path: [
{
...output.paths,
...{
questionIdx: question.questionIdx,
question: question.question,
answerLabel: question.options.map((option) => {
option.answerLabel;
}),
linksTo:
question.options.map((option) => option.linksTo) || undefined,
},
},
],
};
return obj;
}),
};
return aggregateData(mockData, result, startAgain);
}
2
Answers
I first reshape the data for easy access to questions by their id. Then I visit each node, keeping track of the current path, while storing each complete path into the
result
.Before I give you the function, let’s define the interfaces that data structures. It often helps me understand(hope I didn’t make a mistake there):
Now I was able to create the recursive function that iterates through the options and constructs the paths: