Skip to content

Instantly share code, notes, and snippets.

@kerrishotts
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kerrishotts/fd77b4750a37349f13da to your computer and use it in GitHub Desktop.
Save kerrishotts/fd77b4750a37349f13da to your computer and use it in GitHub Desktop.
Value for Key Path -- Deep Object Property Inspection
var x = {
a: {
b: [
{ c: 2, d: 3 },
{ c: 3, d: 4 }
]
},
f: null
};
Object.prototype.valueForKeyPath = valueForKeyPath;
console.log ( JSON.stringify(x.valueForKeyPath( "a.b[1].c", 99 )) );
/**
* Returns a value for the specified keypath. If any intervening
* values evaluate to undefined or null, the entire result is
* undefined or null, respectively.
*
* If you need a default value to be returned in such an instance,
* specify it after the keypath.
*
* Note: if `o` is not an object, it is assumed that the function
* has been bound to `this`. As such, all arguments are shifted by
* one position to the right.
*
* Key paths are of the form:
*
* object.field.field.field[index]
*
* @param {object} o the object to search
* @param {string} k the keypath
* @param {*} d (optional) the default value to return
* should the keypath evaluate to null or
* undefined.
* @return {*} the value at the keypath
*
* License MIT: Copyright 2014 Kerri Shotts
*/
function valueForKeyPath ( o, k, d ) {
if (o === undefined || o === null) {
return (d !== undefined) ? d : o;
}
if ( !(o instanceof Object) ) {
d = k;
k = o;
o = this;
}
var v = o;
// There's a million ways that this regex can go wrong
// with respect to JavaScript identifiers. Splits will
// technically work with just about every non-A-Za-z\$-
// value, so your keypath could be "field/field/field"
// and it would work like "field.field.field".
v = k.match(/([\w\$\\\-]+)/g)
.reduce( function ( v, keyPart ) {
if (v === undefined || v === null) {
return v;
}
try {
return v[ keyPart ];
} catch ( err ) {
return undefined;
}
}, v );
return ((v === undefined || v === null) &&
(d !== undefined) ) ? d : v;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment