4

I've got an array of question and different answers (which I build dynamically, so the number of entries and different answers can vary):

var qaArray = [
    { question: "Question", answer: "Answer A"},
    { question: "Question", answer: "Answer B"},
    { question: "Question", answer: "Answer B"},
    { question: "Question", answer: "Answer C"},
    { question: "Question", answer: "Answer A"},
    { question: "Question", answer: "Answer B"},
    { question: "Question", answer: "Answer C"},
    { question: "Question", answer: "Answer A"},
    { question: "Question", answer: "Answer B"},
]

I need a function to build another array object from this, which would hold the 'answer' and 'count', in this case it would be:

[
    { answer: "Answer A", count: 3 },
    { answer: "Answer B", count: 4 },
    { answer: "Answer C", count: 2 },
]

Is there an easy method to do this, without straight forward loops?

1
  • I will recommend you to use lodash here and use groupBy to perform it easily Commented Dec 14, 2017 at 11:10

4 Answers 4

3

If ES6 is not a problem, it can be done by:

var qaArray = [
    { question: "Question", answer: "Answer A"},
    { question: "Question", answer: "Answer B"},
    { question: "Question", answer: "Answer B"},
    { question: "Question", answer: "Answer C"},
    { question: "Question", answer: "Answer A"},
    { question: "Question", answer: "Answer B"},
    { question: "Question", answer: "Answer C"},
    { question: "Question", answer: "Answer A"},
    { question: "Question", answer: "Answer B"},
];

var result = [...new Set(qaArray.map(q => q.answer))].map(a => ({ answer: a, count: qaArray.filter(e => e.answer === a).length }));

console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

2

If you are looking for solution without reduce or forEach, here is a verbose way using lodash.

_.countBy will give you close result, but if you want to transform it into array as you want, use mapValues.

_.chain(qaArray)
.countBy('answer')
.mapValues(function(value, key) {
  return { answer: key, count: value }
})
.values()
.value()

Comments

2

You can use reduce for this. Concept is to push element to accumulator if it doesn't exist and increment the count if it does.

Please find below solution

var qaArray = [
    { question: "Question", answer: "Answer A"},
    { question: "Question", answer: "Answer B"},
    { question: "Question", answer: "Answer B"},
    { question: "Question", answer: "Answer C"},
    { question: "Question", answer: "Answer A"},
    { question: "Question", answer: "Answer B"},
    { question: "Question", answer: "Answer C"},
    { question: "Question", answer: "Answer A"},
    { question: "Question", answer: "Answer B"},
]


result = qaArray.reduce((acc, item) => {
  var exist = acc.find(x => x.answer === item.answer);
  if (exist) {
    exist.count += 1;
  } else {
    acc.push({
      answer: item.answer,
      count: 1
    })
  }
  return acc;
}, []);


console.log(result);

Comments

1

You can use Map to key your answers then reduce over the data to get counts, like so:

var result = Array.from(qaArray.reduce((acc, { answer }) => {
  const current = acc.get(answer) || { answer, count: 0 };
  current.count++;
  return acc.set(answer, current);
}, new Map()).values());

console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.