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.