// Problem:
/*
- Write method findPath
- Should take two params:
- object
- keys separated by dots as string
- Return value if it exists at that path inside the object, else return undefined
*/
var obj = {
a: {
b: {
c: 12,
j: false
},
k: null
}
};
// Solution:
const findPath = (object, path) => {
let i=1;
const pathList = path.split('.');
let obj = object[pathList[0]];
while(i<pathList.length) {
if(typeof obj === 'object') {
obj = obj[pathList[i]];
i++;
} else {
return undefined;
}
}
return obj;
};
// cases
console.log(findPath(obj, 'a.b.c')); // 12
console.log(findPath(obj, 'a.b')); // {c: 12, j: false}
console.log(findPath(obj, 'a.b.d')); // undefined
console.log(findPath(obj, 'a.c')); // undefined
console.log(findPath(obj, 'a.b.c.d')); // undefined
console.log(findPath(obj, 'a.b.c.d.e')); // undefined
console.log(findPath(obj, 'a.b.j')); //false
console.log(findPath(obj, 'a.b.j.k')); //undefined
console.log(findPath(obj, 'a.k')); //null
thanks
Top comments (19)
Recursion makes for a simpler solution:
As Frank Wisniewski suggests, try Optional Chaning.
It works on more than just object properties as well. It also lets you optionally call functions.
Yes. Optional chaining is latest feature and might not be used (or enabled) everywhere. If someone is using then cool otherwise we need to follow traditional way.
This confused me initially because of the function name - I thought we were going to find a path to a property with a given value, but we're actually doing the opposite. A better name might be
getPropertyWithPath
findPath
similar togetPropertyPath
. I hope people would get it as I am referring to object.Does that really make sense?
gives the same result
True, but I ΓΎink Γ°is is more for backwards compatibility.
But yes, newer code should probably use Optional Chaining.
Yes. Optional Chaining is the best and more readable.
But this isn't really doing the same thing? It's not dynamic
I don't understand what you mean by that..
This could be an impossible case as no one could assign key as dot. Anyhow, my solution is to cover the use cases mentioned.
I think you forgot you can format objects like JSON (JavaScript Object Notation):
I was referring to real world scenario. No one uses any object key as dot alone.
Usually, programmers give readable key name based on their requirement.
Everything has its corner cases, I am generalizing concept to find the path. It is not that I need to cover all worst cases.
Hope you guys get it. Also, it would be better if you guys provide solution for the case you are mentioning. That might worth for the people came across this article.
Thank you.
The simplest solution would be to do away with
split
and instead consider a token-based approach:"."
refers to a field called"."
on the root, whereas"foo.."
refers to a field called"."
on the nested object at root-key"foo"
. And then"foo...bar"
refers to afoo->.->bar
path.However, this also causes some ambiguity:
foo.....bar
could be eitherfoo->.->.->bar
orfoo->...->bar
.A generalized solution would then use escape sequences. e.g.
\.
for a dot literal,\\
for a backslash literal, but that naturally makes parsing the path ever so more complex.I like Γ°is approach.
Sure it requires some more complexity and probably takes longer (but not too much) than
.split(char_seq)
but it gets Γ°e job done and better.Γis could be solved by checking Γ°e more specific case (
foo->.->.->ba
) first and if Γ°at fails try Γ°e simpler one(s).Of course it won't be perfect but it can at least try to figure out intentions.
A
Symbol
is a valid key πYou can also directly define "
.
" in the object declaration as well.Γat's why Γ°ey have a
.toString()
meΓΎod, I believe.Symbols in template strings =
TypeError: can't convert symbol to string
:)