so i've been working on problem and i found the solution but I would like please someone to explain me further why this works actually
const game = {
team1: 'Bayern Munich',
team2: 'Borrussia Dortmund',
score: '4:0',
scored: ['Lewandowski', 'Gnarby', 'Lewandowski', 'Hummels'],
date: 'Nov 9th, 2037',
odds: {
team1: 1.33,
x: 3.25,
team2: 6.5,
},
};
So, having the above object I was trying to : create an object called 'scorers' which contains the names of the players who scored as properties, and the number of goals as the value. In this game. I came with this solution :
const scorers = {};
for (const player of game.scored) {
scorers[player] ? scorers[player] : (scorers[player] = 1);
};
console.log(scorers);
CodePudding user response:
You start by creating a new empty object, then iterate over all the players that are in the game.scored array. What the next line (conditional operator or ternary) does is the following:
if (scorers[player])
scorers[player] ;
else
scorers[player] = 1;
Ternary operators work as follows: <condition> ? <return if true> : <return if false>
. You can also chain ternary operators: <condition1> ? <return if true> : (<condition2> ? <return if true> : <return if false>)
In the "if" condition, if you pass only a variable, it compares it with true
. Basically its if (scorers[player]===true)
, which checks if the player
key exists in the object scorers. If it does, then it increments its score by 1, if not, it creates it with value 1.
Hope you could understand from my brief explanation!
CodePudding user response:
It works because it's (ab)using the conditional operator purely for the side-effects in its second and third operands, ignoring its result. The first operand is evaluated, then either the second (doing the
) or third (doing the assignment) is evaluated. scorers[player]
will be undefined
if you haven't assigned anything for that property yet, which is falsy, so it'll evaluate the third operand (scorers[player] = 1);
; if you have assigned something to scorers[player]
, it'll be a number other than 0
, so it'll be truthy, and the operator evaluates the second operand (scorers[player]
) instead.
The code does the same thing this possibly-clearer code does:
const scorers = {};
for (const player of game.scored) {
if (scorers[player]) {
scorers[player] ;
} else {
scorers[player] = 1;
}
}
console.log(scorers);
(Side note: You don't put ;
after the block attached to a for
.)
Another way you'll commonly see this written is this:
const scorers = {};
for (const player of game.scored) {
scorers[player] = (scorers[player] ?? 0) 1;
// Or before the `??` operator was added:
// scorers[player] = (scorers[player] || 0) 1;
}
console.log(scorers);
If scorers[player]
is undefined
, the nullish coalescing operator (??
) will evaluate scorers[player] ?? 0
to be 0
, so we add one to it. Otherwise it'll be the value of scorers[player]
, so we increase it by one.
CodePudding user response:
When you loop through the game.scored
. You have the decision logic to check if the scorers[player]
have this player
yet. if Yes plus one to that player. if Not, add that player to the scorers
object and set the value to 1.