All questions

Get

Premium

Get

You've got a deeply nested object — an API response, a config tree, a form-state blob — and you need to read a value buried inside it. Optional chaining (obj?.a?.b?.c) covers the static case, but when the path is data ('a.b.c' from a config file, a query string, a permission key), you need a function. Implement get(obj, path, defaultValue?) — the same shape lodash's _.get ships.

get walks the path one segment at a time and returns the value at the end. If any intermediate segment is missing — or if the final value is undefined — it returns defaultValue instead. Critically, null is a real value; only undefined triggers the default.

Signature

get(
  obj: unknown,                        // root object or array
  path: string | (string | number)[],  // 'a.b[0].c' OR ['a', 'b', 0, 'c']
  defaultValue?: unknown               // returned when missing or undefined
): unknown

Examples

// basic dot path
get({ a: { b: 1 } }, 'a.b');
// → 1
// missing path with default
get({ a: { b: 1 } }, 'a.c.d', 'fallback');
// → 'fallback'
// bracket index into an array
get({ users: [{ name: 'Ana' }, { name: 'Bob' }] }, 'users[1].name');
// → 'Bob'
// array path — escape hatch for keys with special chars
get({ 'a.b': { c: 7 } }, ['a.b', 'c']);
// → 7
// null is a real value — NOT replaced by default
get({ a: { b: null } }, 'a.b', 'fallback');
// → null

Notes

  • Path parsing — accept both string ('a.b[0].c') and array (['a', 'b', 0, 'c']) forms. Bracket notation [n] reads array indices; dots separate object keys.
  • Default trigger — return defaultValue only when the resolved value is strictly undefined OR when an intermediate segment can't be accessed (null/undefined parent). A leaf that's null, 0, '', or false is a real value — return it as-is.
  • Fail fast on null/undefined intermediates — walking into null.foo must NOT throw a TypeError. Detect the dead end and return defaultValue.
  • String paths can't represent every key — keys containing dots ('a.b' as a single key) can't be expressed in string form. That's why the array path exists.
  • No need to handle — escape sequences ('a\\.b'), function calls in paths, or assignment. Read-only access is the whole API.

Unlock the solution & editor

  • Runnable editor + tests

    Solve in the browser with instant Jest feedback.

  • Detailed solutions

    Walkthroughs, edge cases, and complexity notes.

  • Multi-framework variants

    React, Vue, Vanilla, Angular — same question, different stacks.

Upgrade to Premium