Hola, estoy llamando a una API donde devuelve un objeto que contiene preguntas y respuestas como esta
{ "questions":[ { "id":1, "questionHeader":"Some question header", "questionText":"Some question text?", }, { "id":2, "questionHeader":"Some question header", "questionText":"Some question text?", }, ], "answers":[ { "id":1, "questionId":1, "answer":"Some answer", }, { "id":2, "questionId":1, "answer":"Some answer", }, { "id":3, "questionId":2, "answer":"Some answer", }, ] }Lo que estoy tratando de lograr es obtener las respuestas incrustadas dentro de su pregunta respectiva en función de una identificación de pregunta y una respuesta de pregunta. Entonces, para lo anterior, estoy tratando de lograr algo como lo siguiente.
{ "questions":[ { "id":1, "questionHeader":"Some question header", "questionText":"Some question text?", "answers":[ { "id":1, "questionId":1, "answer":"Some answer", }, { "id":2, "questionId":1, "answer":"Some answer", }, ] }, { "id":2, "questionHeader":"Some question header", "questionText":"Some question text?", "answers":[ { "id":3, "questionId":2, "answer":"Some answer", }, ] }, ], }Tengo algo que agrega algunas respuestas pero no como una matriz de objetos por pregunta. Actualmente tengo esto
const newItem = data.questions.map((t1) => ({ ...t1, ...data.answers.find((t2) => t2.questionId === t1.id), })); console.log(newItem);He configurado un JSFiddle . ¿Cómo puedo lograr el resultado deseado?
Gracias
Indexe las preguntas por ID primero, luego repita las respuestas. El ID de la pregunta facilitará el acceso a la pregunta asociada: solo use la notación de corchetes para buscarla en el objeto indexado y podrá acceder a las respuestas de esa pregunta. Una vez finalizada la iteración, vuelva a convertir las preguntas en una matriz.
const data={questions:[{id:1,questionHeader:"Some question header",questionText:"Some question text?"},{id:2,questionHeader:"Some question header",questionText:"Some question text?"}],answers:[{id:1,questionId:1,answer:"Some answer"},{id:2,questionId:1,answer:"Some answer"},{id:3,questionId:2,answer:"Some answer"}]}; const questionsById = Object.fromEntries( data.questions.map(question => [question.id, { ...question, answers: [] }]) ); for (const answer of data.answers) { questionsById[answer.questionId].answers.push(answer); } const output = Object.values(questionsById); console.log(output); Lo anterior es O(n) porque no hay bucles anidados. Si desea modificar su enfoque de bucle anidado ( O(n ^ 2) ) para que funcione. .filter en lugar de .find para que pueda obtener una serie de respuestas y prefije la propiedad en el objeto allí con answers: en lugar de difundir.
const data={questions:[{id:1,questionHeader:"Some question header",questionText:"Some question text?"},{id:2,questionHeader:"Some question header",questionText:"Some question text?"}],answers:[{id:1,questionId:1,answer:"Some answer"},{id:2,questionId:1,answer:"Some answer"},{id:3,questionId:2,answer:"Some answer"}]}; const newItem = data.questions.map((t1) => ({ ...t1, answers: data.answers.filter((t2) => t2.questionId === t1.id), })); console.log(newItem);Array#filter se puede usar para encontrar todas las respuestas con una identificación de pregunta específica. (Tenga en cuenta que Array#find solo devuelve el primer elemento que cumple una condición).
const data={questions:[{id:1,questionHeader:"Some question header",questionText:"Some question text?"},{id:2,questionHeader:"Some question header",questionText:"Some question text?"},],answers:[{id:1,questionId:1,answer:"Some answer"},{id:2,questionId:1,answer:"Some answer"},{id:3,questionId:2,answer:"Some answer"},]}; const newItem = data.questions.map((t1) => ({ ...t1, answers: data.answers.filter((t2) => t2.questionId === t1.id), })); console.log(newItem);