admin 管理员组

文章数量: 1086019

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
    }
  }
]

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
    }
  }
]
Share Improve this question edited Dec 17, 2018 at 13:45 mplungjan 178k28 gold badges182 silver badges240 bronze badges asked May 29, 2018 at 20:55 PhoenixPhoenix 4453 gold badges6 silver badges15 bronze badges 6
  • 2 please add your try. btw, why different keys and an array. if different keys are wanted, why not use just a single object? – Nina Scholz Commented May 29, 2018 at 20:58
  • Agree. Or flatten the objects in array and add a mon property like 'question: 1. Please note it is expected you show what you have tried. Stackoverflow is not a free code writing service or "how to" tutorial service – charlietfl Commented May 29, 2018 at 21:00
  • ... is not an operator! – Felix Kling Commented May 29, 2018 at 21:07
  • 2 The structure of your data is unfavorable . Why do you have an array of objects where each object has a different property name? Either have a single object with all questions or an array where each object has the same structure. – Felix Kling Commented May 29, 2018 at 21:08
  • 1 I see your point, but imagine you have list of question from Source A and need to pare with the answers from Source B. And Source B only stores the answer. – Phoenix Commented May 29, 2018 at 21:45
 |  Show 1 more ment

5 Answers 5

Reset to default 2

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/npm/[email protected]/lodash.min.js"></script>

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; }

While I agree with Felix's ment 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.

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)

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>

本文标签: ecmascript 6How can I merge an array of Objects with same keys in ES6 javascriptStack Overflow