Reputation: 711
I am currently working through the Eloquent JavaScript tutorial - Recognizing text.
I have a hard time understanding where the object assignment takes place for the else clause of the condition inside my for
/ of
loop. The only assignment I see is if findIndex
returns -1, yet when I run the code it also creates an object for all values returning true
. How is this possible that it has a name value and where does this get assigned?
function countBy(array, groupName) {
let counts = [];
for (let item of array) {
let name = groupName(item);
let known = counts.findIndex(count => count.name == name);
if (known == -1) {
counts.push({ name, count: 1 });
} else {
counts[known].count++;
}
}
return counts;
}
console.log(countBy([1, 2, 3, 4, 5], n => n > 2));
// → [{name: false, count: 2}, {name: true, count: 3}]
Upvotes: 0
Views: 133
Reputation: 711
findIndex(
) gets called on an empty array the first time ALWAYS returning -1 and therefore ALWAYS instantiating an object in the if(known == -1)
clause.
Upvotes: 0
Reputation: 85837
The countBy
function partitions an array into segments labeled with names returned from the specified callback function.
In your case the callback function is n => n > 2
, which can return true
or false
, so your input array will be partitioned into segments named true
and false
.
In the code, counts
is the array of segments seen so far.
let known = counts.findIndex(count => count.name == name);
checks whether we have seen a segment whose name is name
before. If we have, its index is in known
and we can increment its count directly. If not (known == -1
), we add it as a new segment with an initial count of 1
and a name of name
.
Upvotes: 2