I am trying to achieve something a bit complex.
I am working on a grouping feature where I have to get the items containing the key checked: true
then I need to put them together within the key/array named questionGroup
in the first item in the array with checked: true
and then deleting the other items that were grouped.
See the structure of the data:
const dummyQuestions = [
{
id: 1,
checked: false,
question: {...},
questionGroup: []
},
{
id: 2,
checked: true,
question: {...},
questionGroup: []
},
{
id: 3,
checked: false,
question: {...},
questionGroup: []
},
{
id: 4,
checked: true,
question: {...},
questionGroup: []
},
{
id: 5,
checked: true,
question: {...},
questionGroup: []
}
];
So lets say you clicked on a certain button which fires a grouping function, as you noticed index 1
, 3
and 4
have checked: true
, so this must happen:
const dummyQuestions = [
{
id: 1,
checked: false,
question: {...},
questionGroup: []
},
{
id: 2,
checked: true,
question: {...},
questionGroup: [
{
id: 2,
checked: true,
question: {...},
questionGroup: []
},
{
id: 4,
checked: true,
question: {...},
questionGroup: []
},
{
id: 5,
checked: true,
question: {...},
questionGroup: []
}
]
},
{
id: 3,
checked: false,
question: {...},
questionGroup: []
}
];
That's how the data must be after grouping it.
Do you get the idea?
I created a reproducible demo => https://codesandbox.io/s/ts-react-grouping-odxs1?file=/src/App.tsx
EDIT
This is the relevant code:
const handleGroupQuestions = (): void => {
const questionAddedCopy: VariableConfig[] = [...questionAdded];
// Only the questions with checked === true will be grouped.
const filteredCopy: VariableConfig[] = questionAddedCopy.filter(
(q: VariableConfig) => q.checked === true
);
const grouped: VariableConfig[] = [
...questionAdded.filter((q: VariableConfig) => filteredCopy.includes(q))
];
for (let i = 0; i < grouped.length; i++) {
// Here I compare the ids and I put them together into the key questionGroup
if (filteredCopy[i].id === grouped[i].id) {
// I had to set any instead of VariableConfig type because otherwise TS throws an error
addQuestion((q: any) => {
const questionsCopy = [...q];
const mergedQuestions: VariableConfig[] = [
...questionsCopy,
{ ...grouped[i], questionGroup: grouped }
];
// With this `unique` function what I am trying to achieve (which I am not) is
// to have a unique ID per every question/item in the array.
// I need to add the questions to questionGroup to the highest item containing check = true
// I need to delete from the main array, the items going inside questionGroup.
const unique = [
...mergedQuestions.filter((c) => c.id !== questionsCopy[i].id)
];
return unique;
});
break;
}
}
};
And to explain more in deep and to answer your questions.
We see that the first item in the array with checked: true
is the item with the id 2
, so that will be the place where I have to stored the other items with checked: true
because that is the highest item in the array, then I need to delete from the array the items that were grouped into questionGroup
.
The id 2
in this case is repeated and that is a requirement, because one id is for the parent and the other one within questionGroup
is its own child, get it? Like if it is storing itself into questionGroup
.
This is just a grouping functionality where I am saving some steps. Imagine every item contains a checkbox, so the items that you want to group, you have to check them first, then click the GROUP THEM
button, the checked items disappear and then get together into the highest checked index, keeping its id
and storing itself as well.
Take a look at the arrays I posted. There you can see what is the exact output I need.