I am sure there is already an answer as well as an "easy" solution to this, but I did not find something in the last hour.
So I have this object:
[
{
"win": false,
"switched": false
},
{
"win": false,
"switched": false
},
{
"win": true,
"switched": true
},
{
"win": true,
"switched": true
}
]
which is showing the results of four monty-hall games. I want to create an object from this array that would have the following structure:
{
switched: {
played: 2,
won: 2
},
put: {
played: 2,
lost: 2
}
}
So actually if the object in the upper array has switched: true I want to increase the value of switched["played"]by 1 and it has also won: true I want to increase the value of the keys switched["won"] also by one. Vice versa for switched: false I wand to put everything in the results-object under the key put.
I tried some rather embarrassing approaches with reduce, but I think there must be an "easier" way (mine did not work at all...)
const items = [{
win: false,
switched: false
},
{
win: false,
switched: false
},
{
win: true,
switched: true
},
{
win: true,
switched: true
}
];
const res = items.reduce(
(acc, cur) => {
// If your current item is switched
return cur["switched"]
? { // ... deal with the switched part, leave the rest as is
...acc,
switched: {
played: acc.switched.played + 1, // increase the played counter by 1, based on whatever your accumulator currently has
won: acc.switched.won + Number(cur.win) // cast your win property to number (true -> 1, false -> 0) and increase accordngily
}
}
: { // ... otherwise deal with the put part, leave the rest as is
...acc,
put: {
played: acc.put.played + 1,
lost: acc.put.lost + Number(!cur.win) // negate your win so that it reflects a loss, cast to number and increase accordingly
}
};
},
// Initialize your accumulator
{
switched: {
played: 0,
won: 0
},
put: {
played: 0,
lost: 0
}
}
);
console.log(res);
I think it might help you
const data = [{"win": false,"switched": false},{"win": false,"switched": false},{"win": true,"switched": true},{"win": true,"switched": true}];
const initScores = {
switched: {
played: 0,
won: 0,
},
put: {
played: 0,
lost: 0,
}
};
const result = data.reduce((acc, {win, switched})=> {
if (switched) {
acc.switched.played += 1;
acc.switched.won += win ? 1 : 0;
} else {
acc.put.played += 1;
acc.put.lost += !win ? 1 : 0;
}
return acc;
}, initScores);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0 }
With Array.prototype.reduce, you can supply the logic based on the accumulated object acc and the current game curr.
In the case that curr had been switched, you must assign the switched property to acc. However, it may be undefined, so you should assign it to a default object if this happens.
The same login applies to the other part of the problem. Regarding put property, just replace all those switched with put and won by lost.
const obj=[{win:false,switched:false},{win:false,switched:false},{win:true,switched:true},{win:true,switched:true}]
const output = obj.reduce((acc, curr) => curr.switched ?
(acc.switched = (
{
won: curr.win ? acc.switched.won + 1 : acc.switched.won,
played: acc.switched.played + 1
}
), acc) :
(acc.put = (
{
lost: !curr.win ? acc.put.lost + 1 : acc.put.lost,
played: acc.put.played + 1
}
), acc),
{
switched: {
won: 0,
played: 0
},
put: {
lost: 0,
played: 0
}
})
console.log(output)