A zero count or false flag disappears during array “cleanup”. filter(Boolean) is concise, but its retention rule may differ from the product requirement. Define missing values separately from meaningful values before choosing a predicate.
1. Boolean does not validate your data
const values = [0, false, '', null, undefined, '0', ' ', 3];
console.log(JSON.stringify(values.filter(Boolean))); // ["0"," ",3]
console.log(values.length); // 8
filter retains elements when its callback returns a truthy value; Boolean converts its input to a boolean. Zero, false and empty strings are removed, while '0' and a space-only string remain. See MDN filter and MDN Boolean.
For a report, zero may represent a measured absence of events while null means missing data. Removing both destroys that distinction. A boolean false may likewise represent an explicit disabled choice.
2. Remove only null and undefined when that is the contract
const values = [0, false, '', null, undefined, '0'];
const present = values.filter(value => value !== null && value !== undefined);
console.log(JSON.stringify(present)); // [0,false,"","0"]
console.log(present.length); // 4
This predicate preserves retained values and types. It does not establish numeric validity, text validity or an object schema: NaN and objects missing required fields still pass. Treat missing-value removal as one step, then apply the relevant validation.
If invalid records should be reported to their source, separate valid records from errors with original indices rather than silently dropping rows. Intentional exclusion is different from validating all input successfully.
3. Define text types and whitespace policy explicitly
const input = ['', ' ', ' ready ', null, 42, '0'];
const labels = input
.filter(value => typeof value === 'string')
.map(value => value.trim())
.filter(value => value.length > 0);
console.log(JSON.stringify(labels)); // ["ready","0"]
This sample label policy discards non-strings, trims the ends and removes empty labels. It does not convert 42 into text. Identifiers or whitespace-sensitive fields may need a different policy, so avoid applying one helper to every field.
The output changes ' ready ' into 'ready'. If you only need validation while preserving exact text, test the trimmed length in a predicate without mapping to a new string.
4. A predicate accidentally returning a number can lose rows too
const rows = [{ count: 0 }, { count: 2 }, { count: -1 }];
const accidental = rows.filter(row => row.count);
const nonnegative = rows.filter(row => row.count >= 0);
console.log(JSON.stringify(accidental.map(row => row.count))); // [2,-1]
console.log(JSON.stringify(nonnegative.map(row => row.count))); // [0,2]
The example demonstrates that truthiness is different from a nonnegative-number rule. These rows are known objects with numeric counts. For arbitrary API data, validate each item and the type and finiteness of count before comparing.
5. Choose predicates around what must remain
| Requirement | Question to resolve |
|---|---|
| Remove missing values | Only null and undefined, or others too? |
| Remove blank labels | May text be trimmed and invalid types discarded? |
| Filter counts | Are zero, negatives and non-finite numbers valid? |
| Filter records | Which schema fields are mandatory? |
Test zero, false, empty strings, whitespace, null and undefined together. Testing only 1 and 2 cannot establish that cleanup preserves meaningful edge cases.
All eight bilingual blocks ran with Node.js, with extra checks for preserving zero, false, NaN and object references. Real forms and APIs were not integrated.




No comments yet. Be the first to share your thoughts.