Skip to content

Instantly share code, notes, and snippets.

@JoshDevHub
Last active January 22, 2025 10:08
Show Gist options
  • Save JoshDevHub/b00125f483d4a1ecc257eaa030916973 to your computer and use it in GitHub Desktop.
Save JoshDevHub/b00125f483d4a1ecc257eaa030916973 to your computer and use it in GitHub Desktop.
Recursive Contains
// 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;
}
@mayorr-star
Copy link

Can I get an iterative approach?

@jconnorbuilds
Copy link

jconnorbuilds commented Jun 9, 2024

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),
  );
}

@tg0xff
Copy link

tg0xff commented Jul 21, 2024

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.

@oyinadeolawoyin
Copy link

oyinadeolawoyin commented Nov 29, 2024

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);
}
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment