/**
* searches deep into an object recursively...
* @param {Object} obj object to be searched
* @param {any} searchValue the value/key to search for
* @param {boolean} [searchKeys] whether to search object keys as well as values. Defaults to `true` if `serchValue` is a string, `false` otherwise.
* @returns {string[]} Paths on the object to the matching results
*/constfindPaths=(obj,searchValue,searchKeys=typeofsearchValue==="string")=>{constpaths=[]constvisited=newSet()constnotObject=typeofsearchValue!=="object"constgvpio=(obj,prefix)=>{for(const[curr,currElem]ofObject.entries(obj)){if(searchKeys&&curr===searchValue){paths.push(prefix+curr)}if(typeofcurrElem==="object"){if(visited.has(currElem))continuevisited.add(currElem)gvpio(currElem,prefix+curr+"/")if(notObject)continue}if(currElem===searchValue){paths.push(prefix+curr)}}}gvpio(obj,"")returnpaths}
Disclaimer:
Be careful though, it won't always include the shortest path!
Finally, at the cost of a tiny bit of memory, you can keep a
Set
of visited objects so you can prevent infinite recursion without a counter.Before:
After:
Output:
Code:
Disclaimer:
Be careful though, it won't always include the shortest path!