pave()

A common question lately has been how to create arbitrary-depth arrays/objects without manually checking if the parent already exists each time. The easiest way to do it is to use a simple helper function like this:
// The function takes four arguments, the last one
//   optional, and returns the value set, as in a normal assignment.
// root -- the root object on which to create the value.
// key -- the key to use, subsequent children separated by dots
//   (even if the names are numerical).
// value -- the value to set.
// type -- the constructor to use for new objects.  Defaults to
//   Object, but you might want to use, say, Array.

function pave(root, key, value, type) {
  // If key is falsy (empty) return it straight away.
  // There are potential (but rare) cases where it
  // may make sense to pass an empty string, and
  // without this it will break things.
  if (!key) return value;

  // Loop over the dot-separated keys.
  for (var p = key.split("."), tp, rv, i = 0;
      // Assign tp and rv for efficiency -- lookups are
      // expensive.
      tp = p[i], rv = root[tp], i < p.length - 1; ++i)

    // Check if the current value is an object (there's no
    // point assigning to primitives) and truthy (remember,
    // null is an object) and if not, overwrite it with a new
    // object of type type.
    root = (typeof rv === "object" && rv)
        || (root[tp] = new (type || Object)());

  // Assign the value with the final key and return it.
  return root[tp] = value;
}
  • Twey
  • deltab -- for the name, and for pointing out that this wasn't as self-evident as I thought.