Formulating this problem is a bit complicated so bear with me.
I'm creating a Frequently Asked Questions (FAQ) component, the records are given as a list of objects, like below:
[
{ "slice_type": "information" },
/* Question 1 */
{ "slice_type": "question" },
{ "slice_type": "content" },
{ "slice_type": "quote" },
{ "slice_type": "content" },
/* Question 2 */
{ "slice_type": "question" },
{ "slice_type": "content" },
{ "slice_type": "image" },
{ "slice_type": "youtube_embed" }
...
]
As you know in a collapsible FAQ, the question is always on the header bloc while the rest of the content lays in the body of the component.
Thus is why I need to group the answers of each questions in a list, I will then be able to fetch the desired answers by the question index, here's what I'd like to get.
[
[
{ "slice_type": "content" },
{ "slice_type": "quote" },
{ "slice_type": "content" },
],
[
{ "slice_type": "content" },
{ "slice_type": "image" },
{ "slice_type": "youtube_embed" }
],
...
]
I'd like to know how I can achieve this result programatically?
Can be done with a forEach(). Since you might have items before your questions actually start(as shown in sample data) you should start your index with -1.
let items = [
{ "slice_type": "information" },
/* Question 1 */
{ "slice_type": "question" },
{ "slice_type": "content" },
{ "slice_type": "quote" },
{ "slice_type": "content" },
/* Question 2 */
{ "slice_type": "question" },
{ "slice_type": "content" },
{ "slice_type": "image" },
{ "slice_type": "youtube_embed" }
]
let groupedItems = [];
let quesIndex = -1;
items.forEach((x) => {
if(x.slice_type == 'question' ){
groupedItems.push([]);
quesIndex++;
}
else if(quesIndex!=-1){
groupedItems[quesIndex].push(x);
}
});
console.log(groupedItems);
Using array#reduce,
You can iterate through the array and for each item check if the slice_type property is equals to "question"
Like so:
let newData = data.reduce((acc, obj) => {
if (obj.slice_type == "question") acc.push([])
else acc[acc.length - 1]?.push(obj)
return acc
}, [])
Demo:
let data = [
{"slice_type": "dataBeforeQuestion"},
/* Question 1 */
{ "slice_type": "question" },
{ "slice_type": "content" },
{ "slice_type": "quote" },
{ "slice_type": "content" },
/* Question 2 */
{ "slice_type": "question" },
{ "slice_type": "content" },
{ "slice_type": "image" },
{ "slice_type": "youtube_embed" }
]
let newData = data.reduce((acc, obj) => {
if (obj.slice_type == "question") acc.push([])
else acc[acc.length - 1]?.push(obj)
return acc
}, [])
console.log(newData)
.as-console-wrapper {min-height: 100%!important; top: 0;}