Skip to content

Instantly share code, notes, and snippets.

@westc
Last active April 4, 2019 19:23
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 westc/755fdada5cc602f20d1154c576ed948a to your computer and use it in GitHub Desktop.
Save westc/755fdada5cc602f20d1154c576ed948a to your computer and use it in GitHub Desktop.
Find the path to a specific value based on a callback function.
/**
* Find the path to a specific value based on a callback function.
* @param {*} base
* The object in which you want to start looking to see if it a match
* according to `callback`.
* @param {function(*, Array<string>, *): boolean} callback
* The function that will be called for each value starting with `base` and
* traversing all of its descendants.
* @param {number=} opt_maxTimeMs
* Optional. Defaults to 3000ms. The maximum amount of time to check before
* simply returning `undefined`.
* @return {Array<string>|boolean|undefined}
* If the desired value is found an array with the path to said `base`. If
* the desired value is not found in the allotted time `undefined` is
* returned. In all other cases `false` is returned.
*/
function findPath(base, callback, maxTimeMs=3000) {
let startTime = +new Date;
let toCheck = [{ value: base, path: [] }]
while (entry = toCheck.shift()) {
let value = entry.value;
let path = entry.path;
if (callback(value, path, base)) {
return path;
}
if (value && 'object' === typeof value) {
toCheck = toCheck.concat(Object.keys(value).map(key => ({ value: value[key], path: path.concat([key]) })));
}
if (new Date - startTime > maxTimeMs) {
return undefined;
}
}
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment