Reputation: 987
I have two arrays: one questions another is answers. I want to add answers array which has the same questionID into questions array answers attribute like this:
const questions = {
total: 18,
page: 1,
questions: [{
firstName: 'testing',
lastName: '001',
citizenType: 'VERIFIED CITIZEN',
imageUrl: 'https://source.unsplash.com/400x400/',
question: '546435645364564356',
createdAt: 1563486386916,
id: '905aa4c9-38b8-4429-a91b-56e819ea53e9',
answers : []
}, {
firstName: 'testing',
lastName: '001',
citizenType: 'VERIFIED CITIZEN',
imageUrl: 'https://source.unsplash.com/400x400/',
question: 'questions',
createdAt: 1563484856214,
id: '69165abc-3327-4d99-856a-290042863247',
answers : []
}, {
firstName: 'testing',
lastName: '001',
citizenType: 'VERIFIED CITIZEN',
imageUrl: 'https://source.unsplash.com/400x400/',
question: 'ffff',
createdAt: 1563475882538,
id: '97a1d4a1-7e6d-4859-93ee-5591918bba87',
answers : []
}]
};
const answers = [
{
citizenType: 'VERIFIED CITIZEN',
createdAt: 1563486386916,
firstName: 'Dan',
questionID: '905aa4c9-38b8-4429-a91b-56e819ea53e9',
id: '905aa4c9-38b8-4429-a91b-56e819ea53e1',
imageUrl: 'https://source.unsplash.com/400x400/',
lastName: 'Jone',
answer: 'answer from Dan Joe',
},
{
citizenType: 'VERIFIED CITIZEN',
createdAt: 1563486386916,
firstName: 'Bill',
questionID: '69165abc-3327-4d99-856a-290042863247',
id: '905aa4c9-38b8-4429-a91b-56e819ea53e2',
imageUrl: 'https://source.unsplash.com/400x400/',
lastName: 'Li',
answer: 'answer from Bill',
},
{
citizenType: 'VERIFIED CITIZEN',
createdAt: 1563486386916,
firstName: 'Steve',
questionID: '97a1d4a1-7e6d-4859-93ee-5591918bba87',
id: '905aa4c9-38b8-4429-a91b-56e819ea53e3',
imageUrl: 'https://source.unsplash.com/400x400/',
lastName: 'Sun',
answer: 'answer from Steve',
},
{
citizenType: 'VERIFIED CITIZEN',
createdAt: 1563486386916,
firstName: 'Steve',
questionID: '111111111',
id: '905aa4c9-38b8-4429-a91b-56e819ea53e3',
imageUrl: 'https://source.unsplash.com/400x400/',
lastName: 'Sun',
answer: 'answer from MissMatch',
},
];
let questionArr = questions.questions;
let answerArr = questionArr[0].answers;
// can use I use map, filter or other pure functions to achieve this?
questionArr.forEach(q => {
answers.forEach(a => {
if (q.id === a.questionID) {
q.answers.push(a);
}
})
})
console.log(questions);
right now the result (questions) is what I want, but just wondering if I can achieve this with some ES6 pure functions, like map filter... Thank you so much!
Upvotes: 1
Views: 1234
Reputation: 138267
If you really want to iterate both arrays (thats O(n * m) time complexity), you could build up a new array:
const result = questions.map(question => ({
...question,
answers: answers.filter(it => it.questionID === question.id),
}));
But I'd rather build up a Map from the questions, then its O(n + m):
const questionByID = new Map(questions.map(q => ([q.id, { ...q, answers: [] }])));
for(const answer of answers)
questionByID.get(answer.questionID).answers.push(answer);
const result = [...questionByID.values()];
Upvotes: 3
Reputation: 51886
Analogous to the suggested solution using Map
, you can use a plain object in a much similar way, constructing it with Object.fromEntries()
:
const questionsObject = Object.fromEntries(questions.map(q => [q.id, q]));
answers.forEach(answer => {
questionsObject[answer.questionID].answers.push(answer);
});
const result = Object.values(questionsObject);
Upvotes: 0
Reputation: 386600
You could store the target arrays in a map and push the answers.
var questions = { total: 18, page: 1, questions: [{ firstName: 'testing', lastName: '001', citizenType: 'VERIFIED CITIZEN', imageUrl: 'https://source.unsplash.com/400x400/', question: '546435645364564356', createdAt: 1563486386916, id: '905aa4c9-38b8-4429-a91b-56e819ea53e9', answers: [] }, { firstName: 'testing', lastName: '001', citizenType: 'VERIFIED CITIZEN', imageUrl: 'https://source.unsplash.com/400x400/', question: 'questions', createdAt: 1563484856214, id: '69165abc-3327-4d99-856a-290042863247', answers: [] }, { firstName: 'testing', lastName: '001', citizenType: 'VERIFIED CITIZEN', imageUrl: 'https://source.unsplash.com/400x400/', question: 'ffff', createdAt: 1563475882538, id: '97a1d4a1-7e6d-4859-93ee-5591918bba87', answers: [] }] },
answers = [{ citizenType: 'VERIFIED CITIZEN', createdAt: 1563486386916, firstName: 'Dan', questionID: '905aa4c9-38b8-4429-a91b-56e819ea53e9', id: '905aa4c9-38b8-4429-a91b-56e819ea53e1', imageUrl: 'https://source.unsplash.com/400x400/', lastName: 'Jone', answer: 'answer from Dan Joe' }, { citizenType: 'VERIFIED CITIZEN', createdAt: 1563486386916, firstName: 'Bill', questionID: '69165abc-3327-4d99-856a-290042863247', id: '905aa4c9-38b8-4429-a91b-56e819ea53e2', imageUrl: 'https://source.unsplash.com/400x400/', lastName: 'Li', answer: 'answer from Bill' }, { citizenType: 'VERIFIED CITIZEN', createdAt: 1563486386916, firstName: 'Steve', questionID: '97a1d4a1-7e6d-4859-93ee-5591918bba87', id: '905aa4c9-38b8-4429-a91b-56e819ea53e3', imageUrl: 'https://source.unsplash.com/400x400/', lastName: 'Sun', answer: 'answer from Steve' }, { citizenType: 'VERIFIED CITIZEN', createdAt: 1563486386916, firstName: 'Steve', questionID: '111111111', id: '905aa4c9-38b8-4429-a91b-56e819ea53e3', imageUrl: 'https://source.unsplash.com/400x400/', lastName: 'Sun', answer: 'answer from MissMatch' }];
targets = new Map(questions.questions.map(o => [o.id, o.answers]));
answers.forEach(o => targets.has(o.questionID) && targets.get(o.questionID).push(o));
console.log(questions);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 4806
try this:
const questions = { total: 18, page: 1, questions: [{ firstName: 'testing', lastName: '001', citizenType: 'VERIFIED CITIZEN', imageUrl: 'https://source.unsplash.com/400x400/', question: '546435645364564356', createdAt: 1563486386916, id: '905aa4c9-38b8-4429-a91b-56e819ea53e9', answers : [] }, { firstName: 'testing', lastName: '001', citizenType: 'VERIFIED CITIZEN', imageUrl: 'https://source.unsplash.com/400x400/', question: 'questions', createdAt: 1563484856214, id: '69165abc-3327-4d99-856a-290042863247', answers : [] }, { firstName: 'testing', lastName: '001', citizenType: 'VERIFIED CITIZEN', imageUrl: 'https://source.unsplash.com/400x400/', question: 'ffff', createdAt: 1563475882538, id: '97a1d4a1-7e6d-4859-93ee-5591918bba87', answers : [] }] };
const answers = [ { citizenType: 'VERIFIED CITIZEN', createdAt: 1563486386916, firstName: 'Dan', questionID: '905aa4c9-38b8-4429-a91b-56e819ea53e9', id: '905aa4c9-38b8-4429-a91b-56e819ea53e1', imageUrl: 'https://source.unsplash.com/400x400/', lastName: 'Jone', answer: 'answer from Dan Joe', }, { citizenType: 'VERIFIED CITIZEN', createdAt: 1563486386916, firstName: 'Bill', questionID: '69165abc-3327-4d99-856a-290042863247', id: '905aa4c9-38b8-4429-a91b-56e819ea53e2', imageUrl: 'https://source.unsplash.com/400x400/', lastName: 'Li', answer: 'answer from Bill', }, { citizenType: 'VERIFIED CITIZEN', createdAt: 1563486386916, firstName: 'Steve', questionID: '97a1d4a1-7e6d-4859-93ee-5591918bba87', id: '905aa4c9-38b8-4429-a91b-56e819ea53e3', imageUrl: 'https://source.unsplash.com/400x400/', lastName: 'Sun', answer: 'answer from Steve', }, { citizenType: 'VERIFIED CITIZEN', createdAt: 1563486386916, firstName: 'Steve', questionID: '111111111', id: '905aa4c9-38b8-4429-a91b-56e819ea53e3', imageUrl: 'https://source.unsplash.com/400x400/', lastName: 'Sun', answer: 'answer from MissMatch', }, ];
questions.questions.map(res=> Object.assign(res,{answers:answers.filter(ele=>ele.questionID === res.id)}))
console.log(questions);
Upvotes: 0