I'm looking to create a nested array based on reading a flat array. An example of the flat array I am reading is this:
const flatItems = [
{
"code": "CODE1",
"title": "Title 1",
"question": "Question 1",
"order": 0,
},
{
"code": "CODE2",
"title": "Title 2",
"question": "Question 2",
"order": 1,
},
{
"code": "CODE3",
"title": "Title 3",
"question": "Question 3",
"order": 2,
},
{
"code": "CODE4",
"title": "Title 4",
"question": "Question 4",
"order": 3,
},
];
And ideally I would like to place this into groups of 'Yes's and 'No's. The flat array is already in the correct order. There will only ever be one item in the 'Yes's but can have many in the 'No's depending on any conditions.
const treeItems = {
question: "Question 1",
options: [
{
value: "Yes",
items: [
{
code: "CODE1",
title: "Title 1"
}
]
},
{
value: "No",
question: "Question 2"
options: [
{
value: "Yes",
items: [
{
code: "CODE2",
title: "Title 2"
}
]
},
{
value: "No",
items: [
{
code: "CODE3",
title: "Title 3"
},
{
code: "CODE4",
title: "Title 4"
}
]
}
]
}
]
};
I am aware that reduce may be the best approach here, but would anyone have any good examples or recommended practices as how I should go about doing this?
CodePudding user response:
Not all questions are included in the output. Does this help you get started?
const flatItems =
[{code: "CODE1",title: "Title 1",question: "Question 1",order: 0,},{code: "CODE2",title: "Title 2",question: "Question 2",order: 1,},{code: "CODE3",title: "Title 3",question: "Question 3",order: 2,},{code: "CODE4",title: "Title 4",question: "Question 4",order: 3,},]
function makeTree(questions = []) {
if (questions.length < 1)
return {
items: [ { code: "END", title: "You said no to everything!" } ]
}
const q = questions[0]
return {
question: q.question,
options: [
{
value: "Yes",
items: [
{
code: q.code,
title: q.title
}
]
},
{
value: "No",
...makeTree(questions.slice(1))
}
]
}
}
console.log(makeTree(flatItems))
.as-console-wrapper {min-height: 100% !important; top: 0}
{
"question": "Question 1",
"options": [
{
"value": "Yes",
"items": [
{
"code": "CODE1",
"title": "Title 1"
}
]
},
{
"value": "No",
"question": "Question 2",
"options": [
{
"value": "Yes",
"items": [
{
"code": "CODE2",
"title": "Title 2"
}
]
},
{
"value": "No",
"question": "Question 3",
"options": [
{
"value": "Yes",
"items": [
{
"code": "CODE3",
"title": "Title 3"
}
]
},
{
"value": "No",
"question": "Question 4",
"options": [
{
"value": "Yes",
"items": [
{
"code": "CODE4",
"title": "Title 4"
}
]
},
{
"value": "No",
"items": [
{
"code": "END",
"title": "You said no to everything!"
}
]
}
]
}
]
}
]
}
]
}
CodePudding user response:
If you want to group these items use "Yes" and "No" as the properties of the final object. Using Array.reduce() sounds solid in this case.
Not sure how you want to group because because your JSON is inconsistent.
const flatItems = [
{
"code": "CODE1",
"title": "Title 1",
"question": "Question 1",
"order": 0,
},
{
"code": "CODE2",
"title": "Title 2",
"question": "Question 2",
"order": 1,
},
{
"code": "CODE3",
"title": "Title 3",
"question": "Question 3",
"order": 2,
},
{
"code": "CODE4",
"title": "Title 4",
"question": "Question 4",
"order": 3,
},
];
const groupedObject = flatItems.reduce((tmpGroupedObject, item) => {
const groupingProperty = item.order < 2 ? "Yes" : "No"; /// grouping decision
if (!Array.isArray(tmpGroupedObject[groupingProperty])) {
tmpGroupedObject[groupingProperty] = []; /// make Obj["Yes"] an array
}
tmpGroupedObject[groupingProperty].push(item);
return tmpGroupedObject;
}, {});
console.log(groupedObject);