Reputation: 445
How can I merge two arrays of Objects that have different keys pairs. I would be OK to use a library or ES6 features.
const listOfQuestions = [{
question1: {
important: true
}
}, {
question2: {
important: false
}
}]
const listOfAnswers = [{
question1: {
answer: false
}
}, {
question2: {
answer: true
}
}]
Expected result:
const result = [{
"question1": {
"important": true,
"answer": false
}
}, {
"question2": {
"important": false,
"answer": true
}
}]
I tried to use spread syntax:
const test = [...listOfQuestions, ...listOfAnswers]
But then I get something very out of what I needed:
[
{
"question1": {
"important": true
}
}, {
"question2": {
"important": false
}
}, {
"question1": {
"answer": false
}
}, {
"question2": {
"answer": true
}
}
]
Upvotes: 0
Views: 12423
Reputation: 171698
This structure is horrible to work with!!
That being said following uses a Map to store copies of question objects then loops through answers to extend objects in Map and finally converts Map values to array
const qMap = questions.reduce((m, q) => {
const qKey = Object.keys(q)[0];
return m.set(qKey, {[qKey]: Object.assign({}, q[qKey])});
}, new Map);
answers.forEach(a => {
const qKey = Object.keys(a)[0];
qMap.get(qKey) && Object.assign(qMap.get(qKey)[qKey], a[qKey]);
});
const res = [...qMap.values()];
console.log(res)
<script>
const questions = [{
question1: {
important: true
}
}, {
question2: {
important: false
}
}]
const answers = [{
question1: {
answer: false
}
}, {
question2: {
answer: true
}
}]
</script>
Upvotes: 0
Reputation: 445
Got very interesting code in the answers. I would like to mention that I also could achieve the result using the lodash method .merge()
.
const result = _.merge(listOfQuestions, listOfAnswers)
const listOfQuestions = [{question1:{important: true}}, {question2:{important: false}}]
const listOfAnswers = [{question1:{answer: false}}, {question2:{answer: true}}]
const result = _.merge(listOfQuestions, listOfAnswers)
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
Upvotes: 2
Reputation: 40778
You can achieve this using the .map()
function and returning a newly created array containing the bool important
as well as the answer
to each question
.
const Q = [{question1:{important: true}}, {question2:{important: false}}]
const A = [{question1:{answer: false}}, {question2:{answer: true}}]
let testArr = Q.map(function(q, i) {
return {
['question' + (i + 1)]: {
important: q['question' + (i + 1)].important,
answer: A[i]['question' + (i + 1)].answer
}
}
}, this);
console.log(testArr)
Upvotes: 1
Reputation: 16705
While I agree with Felix's comment in the OP that the data structure is not conducive to this operation, here is an example of merging these two arrays that assumes the object has only one key (that is the question identifier) and that the answers array always contains an item that corresponds to the questions array:
// jshint esnext: true
const listOfQuestions = [{question1:{important: true}}, {question2:{important: false}}];
const listOfAnswers = [{question1:{answer: false}}, {question2:{answer: true}}];
const merged = listOfQuestions.map((item) => {
const obj = {};
const key = Object.keys(item)[0];
const question = item[key];
const answer = listOfAnswers.find((answer) => {
const answerKey = Object.keys(answer)[0];
return key === answerKey;
})[key];
obj[key] = {...question, ...answer};
return obj;
});
console.log(merged);
Uses the spread syntax, but overall this is probably not the best way to approach this problem.
Upvotes: 1
Reputation: 386881
You could collect the inner properties of every question in an object and render a new object with only one question in a new array.
const
setHash = o => Object.entries(o).forEach(([k, v]) => Object.assign(hash[k] = hash[k] || {}, v));
var listOfQuestions = [{ question1: { important: true } }, { question2: { important: false } }],
listOfAnswers = [{ question1: { answer: false } }, { question2: { answer: true } }],
hash = Object.create(null),
result;
listOfQuestions.forEach(setHash);
listOfAnswers.forEach(setHash);
result = Object.entries(hash).map(([k, v]) => ({ [k]: v }));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1