Reputation: 83
I have an array of objects which I want to turn into an object using Reduce:
const results = [{
person: "person1",
choice: 0,
questionId: "a"
},
{
person: "person1",
choice: 1,
questionId: "b"
},
{
...
}
];
and want to return an object with this expected output:
{
results: [
person1: {
a: [1, 0, 0, 0],
b: [0, 1, 0, 0],
c: [0, 0, 0, 0]
},
person2: {
a: [0, 0, 0, 0],
b: [0, 0, 1, 0],
c: [0, 1, 0, 0]
},
person3: {
a: [0, 0, 0, 1],
b: [0, 0, 0, 0],
c: [0, 0, 0, 0]
}
]
}
Where each a: [...] refers to a count of "choice" [0,1,2,3] for each "question" [a,b,c]. The Person should be the index, and the questionId might be variable (it may include "d" for example").
My attempt:
const results = [{
person: "person1",
choice: 0,
questionId: "a"
},
{
person: "person1",
choice: 1,
questionId: "b"
},
{
person: "person2",
choice: 2,
questionId: "c"
},
{
person: "person2",
choice: 3,
questionId: "b"
},
{
person: "person3",
choice: 2,
questionId: "a"
}
];
people = ["person1", "person2", "person3"];
let responses = results.reduce((init, response) => {
switch (response.segment) {
case people[0]:
init[people[0]][response.questionId].push(response.choice[0])
break;
case people[1]:
init[people[1]][response.questionId].push(response.choice[0])
break;
case people[2]:
init[people[2]][response.questionId].push(response.choice[0]);
break;
default:
break;
}
return init;
});
console.log(responses);
I'm unsure how to initiate the object to allow for appending the questions and getting the format I require?
Thanks very much.
Upvotes: 1
Views: 836
Reputation: 11116
Assuming in your output you meant { "person1": {...}, ...}
instead of [ "person1": {...}, ...]
(as the latter is a syntax error), you can do it using reduce, like this:
const results = [
{ person: "person1", choice: 0, questionId: "a" },
{ person: "person1", choice: 1, questionId: "b" },
{ person: "person2", choice: 2, questionId: "c" },
{ person: "person2", choice: 3, questionId: "b" },
{ person: "person3", choice: 2, questionId: "a" }
];
// create an array of all unique questionIds found in the results array
var questionIds = Array.from(new Set(results.map(result => result.questionId)));
console.log(questionIds);
var resultsObj = {
results: results.reduce((res, {person, questionId, choice}) => {
// if person hasn't been created yet, create them
if (!res[person]) {
// need to do .map here instead of outside so we get fresh array references for each person
res[person] = Object.assign({}, ...questionIds.map(id => ({[id]: [0,0,0,0]})));
}
// log a 1 in the correct slot for the answer given
res[person][questionId][choice] = 1;
return res;
}, {})
};
console.log(resultsObj);
Upvotes: 1