如何在ES6 javascript中合并具有相同键的对象数组?

时间:2018-05-29 20:55:01

标签: javascript ecmascript-6

如何合并具有不同密钥对的两个对象数组。我可以使用库或ES6功能。

const listOfQuestions = [{
  question1: {
    important: true
  }
}, {
  question2: {
    important: false
  }
}]

const listOfAnswers = [{
  question1: {
    answer: false
  }
}, {
  question2: {
    answer: true
  }
}]

预期结果:

const result = [{
  "question1": {
    "important": true,
    "answer": false
  }
}, {
  "question2": {
    "important": false,
    "answer": true
  }
}]

我尝试使用扩展语法:

const test = [...listOfQuestions, ...listOfAnswers]

但是我得到的东西非常符合我的需要:

[
  {
    "question1": {
      "important": true
    }
  }, {
    "question2": {
      "important": false
    }
  }, {
    "question1": {
      "answer": false
    }
  }, {
    "question2": {
      "answer": true
    }
  }
]

5 个答案:

答案 0 :(得分:1)

您可以收集对象中每个问题的内部属性,并在新数组中只显示一个问题的新对象。

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

答案 1 :(得分:1)

虽然我同意Felix在OP中的评论,即数据结构不利于此操作,但这里有一个合并这两个数组的例子,假设该对象只有一个键(即问题标识符),并且 answers 数组始终包含与问题数组对应的项目:

// 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);

使用扩展语法,但总体而言,这可能不是解决此问题的最佳方法。

答案 2 :(得分:1)

您可以使用.map()函数实现此目的,并将包含bool important的新创建数组以及answer返回到每个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)

答案 3 :(得分:0)

答案中有非常有趣的代码。我想提一下,我也可以使用lodash方法.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/lodash@4.17.10/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 4 :(得分:0)

使用这种结构非常糟糕!!

如下所述,使用Map存储问题对象的副本,然后遍历解答以扩展Map中的对象,最后将Map值转换为数组

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>