Debugging challengeBeginner

Loose equality in a deduplicator

Scenario

A data-cleaning step removes duplicates from a stream of parsed values and then finds the index of a target. Users report that 0, "", false and null collapse into one value, that NaN is never found even when present, and that indexOf(NaN) returns -1. Find every equality bug.

1function dedupe(values) {
2 const out = [];
3 for (const v of values) {
4 let found = false;
5 for (const u of out) {
6 if (u == v) { found = true; break; }
7 }
8 if (!found) out.push(v);
9 }
10 return out;
11}
12
13function findIndex(values, target) {
14 for (let i = 0; i < values.length; i++) {
15 if (values[i] === target) return i;
16 }
17 return -1;
18}
19
20console.log(dedupe([0, '', false, null, undefined, '0', NaN, NaN]));
21// [0, null, '0', NaN, NaN] — expected [0, '', false, null, undefined, '0', NaN]
22console.log(findIndex([1, NaN, 3], NaN)); // -1, expected 1
23console.log([1, NaN, 3].indexOf(NaN)); // -1
24console.log([1, NaN, 3].includes(NaN)); // true

Your task

  1. List which pairs among 0, "", false, null, undefined, "0" are == equal, and explain the coercion rules that make them so.
  2. Why is NaN === NaN false? Which built-ins use which equality algorithm?
  3. Rewrite dedupe in O(n) using the right equality semantics, and fix findIndex.
  4. When is == acceptable in modern code?
  5. State the complexity before and after.
DebuggingEdge CasesSystematic Reasoning

Work it out

Write your analysis before revealing anything. The self-check below compares it against what a strong answer contains.

Reveal

Progressive — each section builds on the previous one.

The bug
Why it happens
The fix
Edge cases
Complexity

Self-check

Tick what your analysis covered. Be honest — this feeds your readiness profile.

0/6

Related concepts