Compact IILoading saved progress…

Compact II

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.

Signature

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.
}

Examples

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 }

Notes

  • Falsy values in JavaScript are false, null, undefined, 0, NaN, "", and 0n — all of them get stripped, wherever they sit.
  • String "0" stays — it is a non-empty string, which is truthy. Only the number 0 is falsy.
  • Empty containers survive. If stripping leaves an array or object empty, the empty [] / {} stays — it is still a truthy reference. { a: [0, null] } becomes { a: [] }, not {}.
  • Deep copy, never mutate. Every surviving array and object in the result is a fresh container; the caller's input is untouched.
  • Recurse only into arrays and plain objects. Other object types — Date, Map, class instances — are kept as-is by reference, not traversed.
  • Top-level falsy input is returned unchanged: compactIi(0) is 0, compactIi(null) is null.
Loading editor…