У меня есть массив таких объектов
[
{_id: "5ca8b8ca0f1b2f54646ded9a", question: "Do you like it?", answer: "yes"},
{_id: "5ca8b8ca0f1b2f54646ded99", question: "Do you like it?", answer: "no"},
{_id: "5ca8b8f80f1b2f54646deda1", question: "Where are you?", answer: "home"},
{_id: "5ca8b8f80f1b2f54646deda0", question: "Where are you?", answer: "home"}
]
и я хочу, чтобы он воспроизводился следующим образом:
[
{
"question": "Do you like it?",
"answers": [{"answer": "yes", "count": 1}, {"answer": "no", "count": 1}]
},
{
"question": "Where are you?",
"answers": [{"answer": "home", "count": 2}]
}
]
Я пытался решить эту проблему, но не смог, поэтому любая помощь будет очень признательна. Спасибо
используйте reduce
для создания объектов, сгруппированных по значениям вопросов и ответов, а затем, чтобы отказаться от использования keys
, используйте Object.values()
const input = [
{_id: "5ca8b8ca0f1b2f54646ded9a", question: "Do you like it ?", answer: "yes"},
{_id: "5ca8b8ca0f1b2f54646ded99", question: "Do you like it ?", answer: "no"},
{_id: "5ca8b8f80f1b2f54646deda1", question: "Where are you ?", answer: "home"},
{_id: "5ca8b8f80f1b2f54646deda0", question: "Where are you ?", answer: "home"}
];
const groupByQuestionAndAnswers = Object.values(input.reduce((accu, {question, answer}) => {
if (!accu[question])
accu[question] = {question};
if (!accu[question][answer])
accu[question][answer] = {answer, count: 0};
accu[question][answer].count += 1;
return accu;
}, {}));
const output = groupByQuestionAndAnswers.map(({question, ...res}) => {
return {question, answers: Object.values(res)};
});
console.info(output);
Мы можем использовать Array.find
, чтобы найти пару вопрос-ответ, а затем добавить объект пары вопрос-ответ новый, если пара не существует, или обновить существующий объект пары вопрос-ответ.
Если вопрос исчезнет, а ответ — нет, просто добавьте новый ответ в массив answers
.
Если и вопрос, и ответ существуют, увеличьте свойство ответа count
на 1.
Если сам вопрос отсутствует, добавьте новый объект со свойством question
и свойством answers
и установите count
на 1
.
Затем, наконец, используйте Array.reduce
, чтобы собрать объекты в массив.
const data = [
{_id: "5ca8b8ca0f1b2f54646ded9a", question: "Do you like it ?", answer: "yes"},
{_id: "5ca8b8ca0f1b2f54646ded99", question: "Do you like it ?", answer: "no"},
{_id: "5ca8b8f80f1b2f54646deda1", question: "Where are you ?", answer: "home"},
{_id: "5ca8b8f80f1b2f54646deda0", question: "Where are you ?", answer: "home"}
];
const res = data.reduce((acc, {question, answer}) => {
qFound = acc.find(qa => qa.question === question);
if (qFound){
ansFound = qFound.answers.find(ans => ans.answer === answer);
if (ansFound){
ansFound.count = ansFound.count + 1;
}else{
qFound.answers.push({answer, count:1});
}
}else{
acc.push({
question,
answers: [].concat({answer, count: 1})
});
}
return acc;
},[]);
console.info(res);
Возможный дубликат Удалить дубликаты из массива объектов в JavaScript