Search code examples
javascripttraversal

Searching deeply nested object array for a single key


I am trying to search through a deeply nested array and find if a key exists anywhere inside. I have written up a piece of code which does the traversal, but because it is not recursive (only self calling) it cannot return whether or not it has found anything. It just returns undefined since it reaches the end of the function on one of passes.

I was wondering if there was a way I could do this which would allow me to return true on the first occurrence of a specific key.

Here is a JS bin of what I have been working with so far:

https://jsbin.com/qaxuwajuso/edit?js,console

And here is a direct paste of the code from the above example:

function traverse(item, key) {
    if (typeof item === 'object' && !Array.isArray(item) && item !== null) {
        // Object
        for (let itemKey in item) {
            if (itemKey === key) {
                // Is it possible to return true and break out of the function here?
                console.log('found the key: ' + itemKey + ' With value: ' + item[itemKey]);
            }

            traverse(item[itemKey], key);
        }
    } else if (Array.isArray(item)) {
        // Array
        for (let i = 0; i < item.length; ++i) {
            traverse(item[i], key);
        }
    }
}

Any help would be greatly appreciated. Thank you for your time!


Solution

  • You could use for...in and store result in one var and then check that var before you call function again and break loop if value is found.

    const data = [{"id":"2144d998-4c33-4b03-93d2-f6c675b24508","statePath":"div","props":{"className":"testing","name":[{"first":"John","last":{"statePath":"lastName","anArray":[{"anObject":{"anotherArray":[{"doesItWork":{"statePath":"hello"}}]}}]}},{"first":"Jane","last":{"statePath":"lastName"}}]},"children":"hi"}]
    
    function traverse(item, key) {
      let result = false;
    
      for (var i in item) {
        if (i == key) {
          result = true;
          break;
        }
        if (typeof item[i] == 'object' && !result) {
          result = traverse(item[i], key)
        }
      }
    
      return result
    }
    
    console.log(traverse(data, 'statePath'))