Skip to content

Instantly share code, notes, and snippets.

@JoshDevHub
Created January 24, 2024 19:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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) {
if (typeof object !== "object" || object === null) {
return object === searchValue;
}
for (const value of Object.values(object)) {
if (contains(value, searchValue)) {
return true;
}
}
return false;
}
@Mekintosz
Copy link

So elegant this function is.

@zahrabateninia
Copy link

zahrabateninia commented Feb 23, 2024

Let's add some comments to make things easier to understand:

function contains(object, searchValue){
// base case: if the one of the conditions is met, it means that the object is not an object itself, but rather a primitive value or null
if(typeof object !== "object" || object === null ){
return searchValue === object;
}
// Recursive case: if the object is an Object (but not null), iterate over its values
for (const value of Object.values(object)) { // Object.values(object) takes an object and returns a list containing object's values
// Recursively call contains for each value
if (contains(value, searchValue)) {
return true; // If the searchValue is found in any nested object, return true
}
}
return false
}

@anasamer056
Copy link

anasamer056 commented Mar 1, 2024

Here's another solution that's slightly shorter:

function contains(obj, target) {
  for (let val of Object.values(obj)) {
    if (val === target) return true;
    if (val.constructor === Object) {
      return contains(val, target);
    }
  }
  return false;
} 

@heren1heren
Copy link

can you add more explanation how the function still works even if the input Object contains more than 1 nested object?

@Mekintosz
Copy link

can you add more explanation how the function still works even if the input Object contains more than 1 nested object?

The function loops through a given object, going deeper with every iteration. On every iteration it checks for given serchValue, if the serch value is present it returns true if another object if found it call Itself on that object( contains(foundObject, serchValue) ). If the last nested object is reched and serchValue is not present it returns false.

@JoshDevHub
Copy link
Author

JoshDevHub commented Mar 7, 2024

@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:

const obj = {
  a: {
    foo: "bar"
  },
  b: null,
  c: {
    needle: 42
  }
}

contains(obj, 42) // should return `true`

Your solution can't search multiple objects. It'll search the object under key a: and decide that 42 isn't there. Your solution also doesn't tolerate null values and will error if it encounters one.

Now you can absolutely make things shorter, but doing so can risk losing some clarity.

function contains(obj, target) {
  return obj && Object.values(obj).some((val) => {
    return typeof val === "object" ? contains(val, target) : val === target;
  })
}

I wanted to make it a bit easier to understand what's happening.

@anasamer056
Copy link

@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 😅.

@slic23
Copy link

slic23 commented Mar 18, 2024

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

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