Skip to content

Instantly share code, notes, and snippets.

@Ravlissimo
Forked from killants/findPaths.js
Last active November 10, 2022 04:31
Show Gist options
  • Save Ravlissimo/e6e968a90b018e813f21179bd924a6bd to your computer and use it in GitHub Desktop.
Save Ravlissimo/e6e968a90b018e813f21179bd924a6bd to your computer and use it in GitHub Desktop.
Sharing knowledge
/**
* searches deep into an object recursively...
* @param {Object} obj object to be searched
* @param {any} searchValue the value/key to search for
* @param {Object} [options]
* @param {boolean} options.[searchKeys] whether to search object keys as well as values. Defaults to `true` if `serchValue` is a string, `false` otherwise.
* @param {number} options.[maxDepth=20] maximum recursion depth (to avoid "Maximum call stack size exceeded")
* @returns {string[]} Paths on the object to the matching results
*/
const findPaths = (
obj,
searchValue,
{ searchKeys = typeof searchValue === "string", maxDepth = 20 } = {}
) => {
const paths = []
const notObject = typeof searchValue !== "object"
const gvpio = (obj, maxDepth, prefix) => {
if (!maxDepth) return
for (const [curr, currElem] of Object.entries(obj)) {
if (searchKeys && curr === searchValue) {
// To search for property name too ...
paths.push(prefix + curr)
}
if (typeof currElem === "object") {
// object is "object" and "array" is also in the eyes of "typeof"
// search again :D
gvpio(currElem, maxDepth - 1, prefix + curr + "/")
if (notObject) continue
}
// it's something else... probably the value we are looking for
// compares with "searchValue"
if (currElem === searchValue) {
// return index AND/OR property name
paths.push(prefix + curr)
}
}
}
gvpio(obj, maxDepth, "")
return paths
}
// Big thanks to "https://dev.to/qm3ster"
/*
To search an object for a value
- searches deep into the object using recursive...
RETURN : array with paths on the object to the matching results
--------------------------------------------------------------------------------------------------------------------
obj -> to object to be searched
searchValue -> the value to search
bCompareValuesOnly -> boolean indication to compare values only OR to compare also the properties name ....
maxDeepLevel -> the maximun level this recursive function can get ( to avoid "Maximum call stack size exceeded" )
currDeepLevel -> IGNORE THIS PARAMETER : it's used by the function itself to control deep level
*/
function getValuePathInObject(obj, searchValue, bCompareValuesOnly, maxDeepLevel, currDeepLevel){
var bShowInfo = false ;
maxDeepLevel = ( maxDeepLevel || maxDeepLevel == 0 ) ? maxDeepLevel : 20;
currDeepLevel = currDeepLevel ? currDeepLevel : 1 ;
if( currDeepLevel > maxDeepLevel ){
return [];
} else {
var charSeparator = "/";
var paths = [];
var i=0;
for(var curr in obj){
var currElem = obj[curr];
if( currDeepLevel == 1 && bShowInfo ){
console.log("getValuePathInObject_> Looking property \"" + curr + "\" ");
}
if( !bCompareValuesOnly && curr === searchValue ){// To search for property name too ...
paths.push( curr );
}
if( typeof currElem == "object" ){ // object is "object" and "array" is also in the eyes of "typeof"
// search again :D
var deepPaths = getValuePathInObject( currElem, searchValue, bCompareValuesOnly, maxDeepLevel, currDeepLevel + 1 );
for(var e=0 ; e<deepPaths.length ; e++){
paths.push( curr + charSeparator + deepPaths[e]);
}
} else { // it's something else ... problably the value we are looking for
// compares with "searchValue"
if(currElem === searchValue ){
// return index AND/OR property name
paths.push( curr );
}
}
i++;
}
return paths;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment