I'm trying to check if a key exists in my object.
I don't know where or on which nested object the key could be specifically, I just know the name of the key (or property). It would be very handy for me to have a function allowing to quickly search the object and determine if the property key exists in the object.
To illustrate this, my mock object would be something like this:
const testObject = {
one : {
two : {
three : "hello"
}
}
}
I would expect that a function to find if a key exists would return true
for a property key of "three"
or "one"
, and would return false
for a key of "fooBar"
I have tried the hasOwnProperty
method but it fails.
I'm trying to check if a key exists in my object.
I don't know where or on which nested object the key could be specifically, I just know the name of the key (or property). It would be very handy for me to have a function allowing to quickly search the object and determine if the property key exists in the object.
To illustrate this, my mock object would be something like this:
const testObject = {
one : {
two : {
three : "hello"
}
}
}
I would expect that a function to find if a key exists would return true
for a property key of "three"
or "one"
, and would return false
for a key of "fooBar"
I have tried the hasOwnProperty
method but it fails.
-
If you don't need the value, a simple
JSON.stringify(nestedObjects).indexOf('"thePropName":') !== -1
would probably work. – Emile Bergeron Commented May 16, 2019 at 20:29 -
Note that
JSON.stringify
will remove the key if its value isn't serializable, like a Function. – Emile Bergeron Commented May 16, 2019 at 20:51
3 Answers
Reset to default 4One approach would be with a recursive search function like doesObjectHaveNestedKey()
as shown below ( which this does not require an extra dependency like lodash ):
const object = {
some : {
nested : {
property : {
to : [
{
find : {
foo : [ 1 , 2 , 3 ]
}
}
]
}
}
}
}
/* Define function to recursively search for existence of key in obj */
function doesObjectHaveNestedKey(obj, key) {
if(obj === null || obj === undefined) {
return false;
}
for(const k of Object.keys(obj)) {
if(k === key) {
/* Search keys of obj for match and return true if match found */
return true
}
else {
const val = obj[k];
/* If k not a match, try to search it's value. We can search through
object value types, seeing they are capable of containing
objects with keys that might be a match */
if(typeof val === 'object') {
/* Recursivly search for nested key match in nested val */
if(doesObjectHaveNestedKey(val, key) === true) {
return true;
}
}
}
}
return false;
}
console.log('has foo?', doesObjectHaveNestedKey(object, 'foo') ) // True
console.log('has bar?', doesObjectHaveNestedKey(object, 'bar') ) // False
console.log('has nested?', doesObjectHaveNestedKey(object, 'nested') ) // True
console.log('has cat?', doesObjectHaveNestedKey(null, 'cat') ) // False
The idea here is to:
- look through the keys of the input object "obj" for a key "k" that matches the input "key"
- if a match is found return true, otherwise
- look for any value "val" of "obj" that is able to store nested objects (Explore "Object" types as only these can store nested keys) and
- recursively search a "val" of those types for a match and if found, return true
The answer of Dacre Denny could also be written as:
const hasKey = (obj, key) =>
Object.keys(obj).includes(key) ||
Object.values(obj)
.filter(it => typeof it === "object" && it !== null)
.some(it => hasKey(it, key));
Another recursive function. If the current obj
is an object, look if its keys includes
the target key. If isn't included, recall the function for each obj
value:
const searchKey = (obj, key) =>
obj && typeof obj === "object" &&
(Object.keys(obj).includes(key) ||
Object.values(obj).some(o => searchKey(o, key)));
Try the snippet
const testObject = {
one: {
two: {
three: "hello"
}
},
foo: {
bar: {
foobar: 10
}
}
}
const searchKey = (obj, key) =>
obj && typeof obj === "object" &&
(Object.keys(obj).includes(key) ||
Object.values(obj).some(o => searchKey(o, key)));
console.log(searchKey(testObject, "two")); //true
console.log(searchKey(testObject, "foo")); //true
console.log(searchKey(testObject, "barfoo")); //false
console.log(searchKey(testObject, "foobar")); //true