-
-
Save JoshDevHub/b00125f483d4a1ecc257eaa030916973 to your computer and use it in GitHub Desktop.
// solution to problem #6 in recursive exercises | |
function contains(object, searchValue) { | |
// because `null` has a typof "object", we have to explicitly check | |
// to prevent trying to access `null`'s values (which don't exist) | |
if (typeof object !== "object" || object === null) { | |
return object === searchValue; | |
} | |
for (const value of Object.values(object)) { | |
// An important problem in the code quiz solution is that `return contains()` will only | |
// search the first property of an object, as it will return whatever the result for it is. | |
// If our value was nested within the second property, for example, it would never get checked | |
// even if the first nested object did not contain it. | |
if (contains(value, searchValue)) { | |
return true; | |
} | |
} | |
return false; | |
} |
@JoshDevHub Thanks for taking the time to review my code!
You're absolutely correct. I guess I was sleep deprived when I was writing that code because I can't believe that I missed these bugs 😅.
function nested(objeto, item) {
for (let key in objeto) {
if (objeto[key] === item) {
return true;
}
if (typeof objeto[key] === 'object') {
if (nested(objeto[key], item)) {
return true;
}
}
}
return false;
}
Can I get an iterative approach?
Just adding another recursive solution here that utilizes Array.prototype.some, nice and succinct:
function contains(obj, targetValue) {
if (typeof obj !== 'object' || obj === null) return false;
return Object.values(obj).some(
(value) => value === targetValue || contains(value, targetValue),
);
}
I had originally used a ternary statement (below) as the callback for .some(), which felt a bit easier to read to me, but for the sake of keeping it short, modified to the above.
function contains(obj, targetValue) {
if (typeof obj !== 'object' || obj === null) return false;
return Object.values(obj).some((value) =>
value === targetValue ? true : contains(value, targetValue),
);
}
Came up with this function myself:
function contains(obj, targetVal) {
for (const currentVal of Object.values(obj)) {
if (typeof currentVal === "object") {
return contains(currentVal, targetVal);
}
if (currentVal === targetVal) return true;
}
return false;
}
Felt quite good about it even though I knew that a null
could very easily render it useless. But then I realised that I could just change the third line to: if (typeof currentVal === "object" && currentVal !== null) {
to prevent that from happening.
I thought I needed to search for the keys and values:
function contains(obj, item) {
if (Object.values(obj).length === 0) return false;
else if (item in obj || Object.values(obj).includes(item)) return true;
else {
for (let value of Object.values(obj)) {
return contains(value, item);
}
}
}
@heren1heren Might be easiest to understand by walking through the stack with a debugger.
@anasamer056 Your solution has two important problems, which can be seen by testing like:
Your solution can't search multiple objects. It'll search the object under key
a:
and decide that42
isn't there. Your solution also doesn't toleratenull
values and will error if it encounters one.Now you can absolutely make things shorter, but doing so can risk losing some clarity.
I wanted to make it a bit easier to understand what's happening.