The easy version of compact cleans a single flat array: it removes every falsy value and hands back a new list. Real data is rarely flat. An API response is arrays of objects holding more arrays, and the empty strings, nulls, and 0s you want gone are buried several levels down.
Implement compactIi(value), the deep version. It returns a deep copy of value in which every falsy value has been stripped out of every nested array and every nested plain object, at any depth. Nothing about the input is mutated.
function compactIi(value) {
// Returns a deep copy of `value`:
// - in arrays, drop every falsy element
// - in plain objects, drop every key whose value is falsy
// - recurse into surviving arrays and plain objects
// The input is never mutated.
}
compactIi([1, [0, 2, false], [null, [3, '']]]);
// → [1, [2], [[3]]]
compactIi({ a: { b: 0, c: 2 }, d: { e: null, f: { g: 4, h: '' } } });
// → { a: { c: 2 }, d: { f: { g: 4 } } }
compactIi({
users: [
{ name: 'Ann', age: 0, city: 'NYC' },
{ name: '', age: 31 },
],
total: 2,
cursor: null,
});
// → { users: [{ name: 'Ann', city: 'NYC' }, { age: 31 }], total: 2 }
false, null, undefined, 0, NaN, "", and 0n — all of them get stripped, wherever they sit."0" stays — it is a non-empty string, which is truthy. Only the number 0 is falsy.[] / {} stays — it is still a truthy reference. { a: [0, null] } becomes { a: [] }, not {}.Date, Map, class instances — are kept as-is by reference, not traversed.compactIi(0) is 0, compactIi(null) is null.