easyJS ES5#120

Conteo de caracteres

Prompt

Count each character in a string (case-sensitive). Return an object with character counts.

Solution

function charCount(str) {
  const count = {}
  for (const c of str) count[c] = (count[c] || 0) + 1
  return count
}
Mentor's take

This is the frequency map in its purest form — the primitive that problems 104, 112, 113, and 125 all build on. If a candidate can't produce this in thirty seconds, every histogram-based question downstream falls over, which is why it gets asked despite being "easy". One pass, O(n) time, O(k) space for k distinct characters.

The load-bearing expression is count[c] = (count[c] || 0) + 1 — read it as "current count, defaulting to zero, plus one". The default matters because a missing key reads as undefined, and undefined + 1 is NaN. There is no faster approach to discuss — counting requires touching every character once — so the interview signal moves to details:

  • for...of iterates code points, not UTF-16 code units like str[i] indexing does. For emoji and other astral-plane characters, charCount('𝒳') with for...of counts one character; index-based loops count two half-surrogates. A one-sentence Unicode remark here is cheap and distinctive.
  • Plain object vs Map: a plain object inherits prototype keys, so count['constructor'] before assignment isn't undefined — it's a function, and || 0 actually saves you here by coercing it. Object.create(null) or a Map removes the hazard cleanly; mention it when asked about hostile input.

Red flag: count[c]++ with no default — NaN on first sight of each character, and the object ends up all NaN. It's the same initialize-or-increment miss as in group-and-count, and it's the first thing a reviewer greps for.

Say it: "One pass with initialize-or-increment — the || 0 default exists because undefined + 1 is NaN, and for...of gives me code points instead of surrogate halves."