A co-worker recently asked about searching for properties in a JavaScript object, where the properties could be located in unspecified locations within the object (not nested though). This was the job for a depth-first tree search! I don’t get to post about more traditional computer science topics very frequently, so I thought I’d share my little ES6 recursive search function:
1 2 3 4 5 6 7 8 9 10 11 12 |
let search = (needle, haystack, found = []) => { Object.keys(haystack).forEach((key) => { if(key === needle){ found.push(haystack[key]); return found; } if(typeof haystack[key] === 'object'){ search(needle, haystack[key], found); } }); return found; }; |
Explanation (commented source)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
//creates a `search` function, which accepts a needle (property name, string), //a haystack (the object to search within), found (the recursively added to //list of found properties let search = (needle, haystack, found = []) => { //iterate through each property key in the object Object.keys(haystack).forEach((key) => { //if the current key is the search term (needle), //push its value to the found stack if(key === needle){ found.push(haystack[key]); //return the array of found values to the caller, which is //either the caller of the search function, or the recursive //"parent" of the current search function return found; } //if the value of the current property key is an object, //recursively search it for more matching properties //this can be changed to an else if, if properties should not //be nested if(typeof haystack[key] === 'object'){ search(needle, haystack[key], found); } }); //return the list of found values to the caller of the function return found; }; |
Example
This code can be used like so:
1 2 3 4 5 6 7 8 9 10 11 12 |
let data = { person: 'Mike', address: '123 Street, state, country', relatedCustomers: { childObject: { foo: ['bar'], person: 'Hailey' } } }; search('person', data); // ['Mike', 'Hailey'] |