As my opening contribution, i leave here a method i developed to search inside a JSON object for a specific value (could be or not the name of the ...
For further actions, you may consider blocking this person and/or reporting abuse
Without changing the structure, I would do the following:
const
andlet
, nevervar
.for of
loops instead of imperative key and numeric index iteration.charSeparator
out of the function (or you could inline the"/"
literal)curr
andcharSeparator
once, not in the loop.i
.continue
).undefined
, not truthiness, so passingfalse
and0
won't trigger them.Otherwise, I'd use an inner recursive function so that I can do option parsing once, and then close over one array I will always append to, to avoid allocating intermediate arrays:
Here, I'm also using an options object for convenience, with a smart default for
searchKeys
, since object keys are always strings, even in arrays:I'm also building the
path
string with no duplication. This includes eliminating the inner loop, since we never return an intermediary array back up. The reasonprefix + curr
occurs in 3 places is because in a real search, on most keys none of those conditions will happen, and almost never will two happen together.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!
Not used to see many arrow function (without being small ones, in array.map for example) so i got a bit confused with the parameter line :
{ searchKeys = typeof searchValue === "string", maxDepth = 20 } = {}
Would you mind to explain in a few words why it is there? :)
Thank you in advance.
Sure, this doesn't depend on it being an arrow function, can be in a
function
just as well.This is the equivalent function:
First, we replace the point access with destructuring:
Next, we replace the conditional expressions for defaults with defaults in destructuring AND default in parameter:
Finally, to avoid having to think of a name for the short-lived
arg
binding, we can just YEET it right into the parameter list:We could write it like this:
But that's just more verbose. Destructuring an empty object (if
undefined
is provided) is perfectly adequate, and gives defaults for all keys.Hasn't use "let" before to declare variables, will definitely use now ( Thanks to Sarah Chima for her post "dev.to/sarah_chima/var-let-and-con..." )! :D
Is "for of" more optimized for this kind of methods (recursive), instead of indexed ones ?
I had that "charSeparator" declared inside because at the time i made it i though leaving the option to choose the char used to be received in parameter (but then i just forgot it XD)
That variable "i" .... I just can't even remember why was there ?? :/ My bad !
Tonight i won't be able, but tomorrow right after work, will fix it ! ;)
Thanks a lot for your feedback Mihail :D
If you look in the replies to my above comment, I replied to myself (and then replied again to that comment) with new versions of the code.
I had a similar idea last year :) Take a look at
object-scan
and the filterFn function. Shows where requirements ultimately go hahaa look where ? sorry not finding "object-scan" as told... Would you mind sharing a link, please?
Thanks
Of course! Here you go github.com/blackflux/object-scan
I added to the gist, the optimized function provided by "Mihail Malostanidis" (dev.to/qm3ster) since it is way more "clean". I leaved the old one so you can compare with my first attempt and see the difference. You can always check Mihail comments on this post since he explains his approach to this.
Big thanks to Mihail for his help!!! :)
Was a fully single-recursive implementation part of the goal?
Was my way of thinking, i made this method just to fecth the path in some object which value i knew it exists somewhere. :)