Skip to content

Instantly share code, notes, and snippets.

@netcall-jlo
Created August 8, 2023 07:48
Show Gist options
  • Save netcall-jlo/b936b5824ea8145b41e45bf680588051 to your computer and use it in GitHub Desktop.
Save netcall-jlo/b936b5824ea8145b41e45bf680588051 to your computer and use it in GitHub Desktop.
Allows an object to be searched to try and find a specific key or value. Useful for debugging
/**
* Finds any matches within the given object that satisfy the given search
* function.
*
* @param {Object} object
* Object to search.
* @param {Function} search
* Function that will identify a match. The function is passed the
* key, the value, and the full path. If it returns any truthy value
* then the result will be considered a match.
* @param {String} [path = ""]
* Optional string that forms the basis of the path. This is mainly used
* interally when the function is recursing to keep track of the path to
* get to the current object.
* @param {WeakMap} [map = new WeakMap()]
* A map that keeps track of any object that's been seen before. This
* prevents an infinite loop when dealing with self-referencing objects.
* @return {Array.<Array>}
* An array of responses. Each entry in the array is another array
* containing the full path to get to the value and the value.
*/
function findInObject(object, search, path = "", map = new WeakMap()) {
const results = [];
Object.entries(object).forEach(([key, value]) => {
let fullPath = key;
if (path) {
const suffix = (
(/^[a-zA-Z_$]+$/).test(key)
? `.${key}`
: `[${key}]`
);
fullPath = path + suffix;
}
if (search(key, value, fullPath)) {
results.push([fullPath, value]);
}
if (value && typeof value === "object" && !map.has(value)) {
map.set(value, true);
results.push(...findInObject(value, search, fullPath, map));
}
});
return results;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment