2

Suppose there is a very long and nested JSON and you need to find a specific key value( "domain": "pack" inside that JSON and return the object containing that key value pair. The path to that key is something like item.items.offerings.item.items.offers.item.items.offers.domain The tricky part here is that both items and offers are arrays with multiple objects and all of those objects contain item. So we need to search in each object inside items and offers.

function findDomain(obj) {
    if (obj && typeof obj === 'object') {
      if (obj.domain === 'pack') {
        return obj;
      }
      
      let found = false;
      let result;
      
      for (const key in obj) {
        if (obj.hasOwnProperty(key) && !found) {
          const value = obj[key];
          const childResult = findDomain(value);
          
          if (childResult) {
            found = true;
            result = childResult;
          }
        }
      }
      
      return result;
    }
    
    return null;
  }
  
  const pack = findDomain(a);
  console.log(pack);
//a is the object

I have used recursive method which is working fine, but i am not sure if its the best solution. Is there a better way to solve this without using any library.

Lelouch
  • 53
  • 4
  • Recursion is fine. The other option might be to change the data you're receiving into something that doesn't resemble chaos. As such, since the code works, this isn't really a SO problem - SO deals with code that doesn't work. You may want to visit https://codereview.stackexchange.com to see what they say [but make sure to read their help section first](https://codereview.stackexchange.com/help/) before submitting a question. – Andy Mar 04 '23 at 14:48

1 Answers1

1

Consider using Object.prototype.hasOwnProperty.call instead. You don't need the found variable either. You can just directly return from the loop.

const obj = { a: { b: { c: { d: { e: { domain: "pack" }, f: 0 }, g: { h: 42 } }, i: "" }, j: "", k: [] }, l: true };

function findDomain(obj) {
    if (!obj || typeof obj !== "object") return null;
    
    if (obj.domain === "pack") return obj;
    
    for (const key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            const value = obj[key];
            const childResult = findDomain(value);
            
            return childResult;
        }
    }
    
    return null;
}

console.log(findDomain(obj));

Finally, I used a guard clause to alleviate the nesting, but you could keep it as it was if you want since this does duplicate the return null:

if (obj && typeof obj === "object") {
    // ...
}

return null;
kelsny
  • 23,009
  • 3
  • 19
  • 48