javascriptarraysjsonchart.jssurveyjs

How to analyze/count an array of objects in Javascript


Stack Overflow! This is my very first.

So, say for example I have the following array:

[
    {
        "question1": "Apple",
        "question2": 5,
        "question3": "Item 1"
    },
    {
        "question1": "Apple",
        "question2": 4,
        "question3": "Item 2"
    },
    {
        "question1": "Orange",
        "question2": 4,
        "question3": "Item 2"
    }
]

Each object represents a respondent's answers to each question from a survey, which means the array above has a total of 3 responses.

What I want is to count the answers of each question, like how many in a multiple choice question chose X answer and so on.

The following output should look like this for a single question:

[
    {
        "answer": "Apple",
        "count": 2,
    },
    {
        "answer": "Orange",
        "count": 1,
    }
]

Which means according to the example above I'll need total of 3 arrays (because total 3 questions) of counted answers. Is there any way to achieve this? My goal here is to use ChartJS in React to display charts of the responses of each question.

Final output for a single chart (of a single question, say question1):

[
    {
        "answer": "Apple",
        "count": 2,
    },
    {
        "answer": "Orange",
        "count": 1,
    }
]

Solution

  • This outputs an array of arrays of objects, instead of multiple array variables of objects. Since JavaScript objects preserve insertion order, you don't need to worry about the questions being out of order, assuming they're already in the proper order.

    const data = [{question1:"Apple",question2:5,question3:"Item 1"},{question1:"Apple",question2:4,question3:"Item 2"},{question1:"Orange",question2:4,question3:"Item 2"}];
    
    const newData = Object.values(data.reduce((acc, qna) => {
      for (const [question, answer] of Object.entries(qna)) {
        acc[question] = acc[question] ?? {};
        acc[question][answer] = (acc[question][answer] ?? 0) + 1;
      }
      return acc;
    }, {}))
      .map((answerCount) => Object.entries(answerCount)
        .map(([answer, count]) => ({ answer, count }))
      );
    
    console.log(newData);