class QuizAnswers {
List<MultipleChoiceAnswer> multipleChoiceAnswers;
List<FreeResponseAnswer> freeResponseAnswers; //not relevant to this question
}
class MultipleChoiceAnswer {
int questionId;
// The index of the selected multiple choice question
int answer_selection;
}
The input to my function is a List<QuizAnswers>
.
I want to create an output of Map<Integer, Map<Integer, Long>>
that maps <MultipleChoiceAnswer.questionId : <MultipleChoiceAnswer.answer_selection, total count of answer_selection>
. In other words, I want to create a nested map that maps each multiple choice quiz question to a map representing the total number of selections on each answer choice of that quiz question.
Suppose the input List<QuizAnswers> quizAnswersList
as:
[ {questionId: 1, answer_selection: 2},
{questionId: 1, answer_selection:2},
{questionId: 1, answer_selection:3},
{questionId: 2, answer_selection:1} ]
Then I would want the output to be:
{1 : {2:2, 3:1}, 2: {1, 1}}
Because the question with Id = 1
received two selections on answer choice 2
and 1
selection on answer choice 3
while the question with Id=2
had 1
selection on answer choice 1
.
I have tried
quizAnswersList.stream()
.map(
quizAnswers ->
quizAnswers.getMultipleChoiceAnswers().stream()
.collect(
Collectors.groupingBy(
MultipleChoiceAnswer::getQuestionId,
Collectors.groupingBy(
MultipleChoiceAnswer::getAnswerSelection,
Collectors.counting()))));
Which is giving me an error. I am not very familiar with streams and collectors in general, so I'd love to learn how to do this correctly.
I want to create an
output
ofMap<Integer, Map<Integer, Long>>
that maps <MultipleChoiceAnswer.questionId : <MultipleChoiceAnswer.answer_selection>, total count of answer_selection>.
You were close. You just didn't flatMap
the MultipleChoiceAnswers
onto the stream so you had a nested stream and that was causing the problem.
Based on your edited question, here is what I came up with.
List<MultipleChoiceAnswer> mca =
List.of(new MultipleChoiceAnswer(1, 2),
new MultipleChoiceAnswer(1, 2),
new MultipleChoiceAnswer(1, 3),
new MultipleChoiceAnswer(2, 1));
// more could be added to the List. You only provided one.
List<QuizAnswers> list = List.of(new QuizAnswers(mca));
MultipleChoice
listsquestionId
AnswerSelection
and get a countMap<Integer,Map<Integer,Long>> map = list.stream()
.flatMap(s -> s.getMultipleChoiceAnswers().stream())
.collect(Collectors.groupingBy(
MultipleChoiceAnswer::getQuestionId,
Collectors.groupingBy(
MultipleChoiceAnswer::getAnswerSelection,
Collectors.counting())));
map.entrySet().forEach(System.out::println);
prints
1={2=2, 3=1}
2={1=1}
Questions
QuizAnswer
instances?MulitpleChoiceAnswer
lists. You only provided one of each.They could all be flatmapped
together and processed as above. But I think there could be some differences in the Answers (perhaps for different tests) which you don't want grouped and counted as the same.
Example
If I add the following to the List<QuizAnswers>
List<MultipleChoiceAnswer> mca2 =
List.of(new MultipleChoiceAnswer(1, 2),
new MultipleChoiceAnswer(1, 2),
new MultipleChoiceAnswer(5, 2),
new MultipleChoiceAnswer(5, 2));
And process using the above solution, the output would be
1={2=4, 3=1}
2={1=1}
5={2=2}