The following code uses the reduce method. It outputs the number of times an element appears in the array. If element appears once then it only outputs 1, otherwise if it is a repeated item then it it is added..
let a = ["a", "b", "c", "a", "b"]
const t = a.reduce((aa, ll) => {
const count = aa[ll];
count
?
aa[ll] = count + 1 :
aa[ll] = 1
return aa
}, {})
console.log(JSON.stringify(t))
// output
// { "a":2, "b":2, "c":1 }
Question is regarding the condition in the ternary operation, specifically the count variable. How is the count variable able to resolve true or false.
The concept is called "Truthy" and "Falsy" respectively. Ie anything that is different from false
, 0
, -0
, 0n
, NaN
, null
, undefined
and ""
(empty string) can be evaluated to true
in Javascript
So your assign var counter = aa[ll]
to be the value of the key ll
in object aa
. That's either a number or undefined
. If it's a number !== 0
it's a truthy, if it's 0
or undefined
it's falsy. Thus it can be used in a ternary operatator. Depending on the value of counter
either the value of the first or the second assignment will be returned (but ignored). The return value of an assignment is always the value of the right hand side ...
While you can use also assignments in the expressions of a ternary operator, I personally wouldn't use it that way but write this assignment as follows
const t = a.reduce((aa, ll) => {
aa[ll] = (aa[ll] || 0) + 1;
return aa
}, {})
(aa[ll] || 0)
will return the value of aa[ll]
if it's a truthy or 0
otherwise. Thus, in your case, the result of this expression will always be a number >= 0
. Then you increase the result by 1 (for the currenct occurence of ll
) and assign it back to aa[ll]
. This is much shorter than your original code and IMHO much more readable