Last active
August 29, 2015 14:07
-
-
Save kerrishotts/fd77b4750a37349f13da to your computer and use it in GitHub Desktop.
Value for Key Path -- Deep Object Property Inspection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 )) ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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