Introduction
Recursive search is a technique for traversing a data structure and searching for an element or elements that match a specific condition. In JavaScript, this can be particularly useful when working with complex data structures such as JSON objects.
One common use case for a recursive search in a JSON object is to find a value by its key or to find all values that match a certain condition.
In this article, we will discuss how to carry out recursive search in JSON objects.
Recursive search in JSON object
To illustrate how we can achieve recursive search in JSON objects, we will need to work with some examples.
For example, consider a JSON object representing a list of employees in an organization, with nested objects for each employee's personal and professional information. If we wanted to find the email address of a specific employee, we could use a recursive search function to iterate through the object and return the value of the "email"
key for the matching employee.
To implement a recursive search in a JSON object in JavaScript, we can use a function that takes three arguments: the object to search, the key or condition we want to match, and an optional results array to store the matching values. The function should first check if the object is a primitive value (such as a string, number, or boolean); if it is, it should return the value if it matches the key or condition, or undefined
otherwise. If the object is not a primitive value, the function should iterate over the object's properties and call itself recursively on each property.
Example-1: Find specific value in JSON Object
Here is an example of a recursive search function that finds the value of a specific key in a JSON object:
function search(obj, key) {
if (typeof obj !== "object" || obj === null) {
return obj === key ? obj : undefined;
}
for (const [k, v] of Object.entries(obj)) {
const result = search(v, key);
if (result !== undefined) {
return result;
}
}
return undefined;
}
This function works by using the typeof
operator to check if the input obj
is an object. If it is not, it checks if the value is equal to the key using the strict equality operator (===
) and returns the value if it is, or undefined
otherwise. If the obj
is an object, it uses the Object.entries
method to iterate over the object's properties and calls itself recursively on each property using the search
function itself. If the recursive call returns a value other than undefined
, the value is returned; otherwise, the loop continues until all properties have been searched.
To use this function, we can pass in a JSON object and the key we want to find:
const employees = {
Abhi: {
name: "Abhi",
email: "abhi@example.com",
title: "Manager",
department: "Marketing",
},
Anurag: {
name: "Anurag",
email: "anurag@example.com",
title: "Developer",
department: "Engineering",
},
Vishal: {
name: "Vishal",
email: "vishal@example.com",
title: "Manager",
department: "Marketing",
},
Saurav: {
name: "Saurav",
email: "saurav@example.com",
title: "Designer",
department: "Design",
},
};
const AbhiEmail = search(employees, "abhi@example.com");
console.log(AbhiEmail);
Output
abhi@example.com
This function can be useful for finding a specific value in a complex JSON object, such as a particular employee's email address in the example above.
We can also modify the function to search for values that match a certain condition rather than a specific key. For example, we might want to find all employees who have the title of "Manager". To do this, we can modify the function to accept a condition function as the second argument, which should return a boolean value indicating whether the value matches the condition.
Example-2: Find all values based on condition match
Here is an example of a recursive search function that finds all values that match a condition in a JSON object
function search(obj, fn, results = []) {
if (typeof obj !== "object" || obj === null) {
if (fn(obj)) {
results.push(obj);
}
return results;
}
for (const [k, v] of Object.entries(obj)) {
search(v, fn, results);
}
return results;
}
This function works similarly to the previous version, but instead of returning the first matching value it encounters, it pushes all matching values to the results
array and returns the array at the end. To use this function, we can pass in a JSON object and a condition function that checks for the desired value:
const managers = search(employees, (value) => value === "Manager");
console.log(managers);
Output
[ 'Manager', 'Manager' ]
In this example, the condition function uses the strict equality operator (===
) to check if the value is equal to "Manager". If it is, the value is added to the results
array.
Example-3: Creating a recursive search function
We can use a recursive function to search through a JSON object in JavaScript. The function should take in the current object, the key we are searching for, and the value we are searching for as parameters. Inside the function, we can use a for loop to iterate through the object's keys. If the current key matches the search key and the corresponding value matches the search value, we can return the current object. If the current value is an object, we can call the function recursively with the current value as the new object to search.
Here is an example of a recursive function that searches for a key-value pair in a JSON object. We will re-use our JSON object from previous example:
function searchJSON(obj, key, val) {
let results = [];
for (let k in obj) {
if (obj.hasOwnProperty(k)) {
if (k === key && obj[k] === val) {
results.push(obj);
} else if (typeof obj[k] === "object") {
results = results.concat(searchJSON(obj[k], key, val));
}
}
}
return results;
}
let employeed = {...}; // your JSON object
let key = "name";
let val = "Ramesh";
let results = searchJSON(json, key, val);
console.log(results);
Output:
[
{
name: 'Anurag',
email: 'anurag@example.com',
title: 'Developer',
department: 'Engineering'
}
]
Example-4: Using Array.prototype.filter()
method
The filter()
method from Array.prototype.filter()
creates a new array with all elements that pass the test implemented by the provided function. Here's an example of how we can use the filter()
method to search for a key-value pair in a JSON object:
let json = {
"person1": {
"name": "Rahul",
"age": 25
},
"person2": {
"name": "Amrit",
"age": 30
},
"person3": {
"name": "Ravi",
"age": 35
}
}
let key = "name";
let val = "Rahul";
let results = Object.values(json).filter(person => person[key] === val);
console.log(results);
Output:
[ { name: 'Rahul', age: 25 } ]
Example-5: Using Object.entries
and Array.prototype.filter()
Here we will use Object.entries
along with Array.prototype.filter()
to perform a recursive search through the JSON object:
let json = {
"person1": {
"name": "Rahul",
"age": 25
},
"person2": {
"name": "Amit",
"age": 30
},
"person3": {
"name": "Rekha",
"age": 35
}
}
let key = "name";
let val = "Rahul";
let results = Object.entries(json).filter(entry => entry[1][key] === val).map(entry=>entry[1]);
console.log(results);
Output
[ { name: 'Rahul', age: 25 } ]
Example-6: Using Array.prototype.reduce()
We can also use the reduce()
method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
let json = {
"person1": {
"name": "Rahul",
"age": 25
},
"person2": {
"name": "Amit",
"age": 30
},
"person3": {
"name": "Rahul",
"age": 35
}
}
let key = "name";
let val = "Rahul";
let results = Object.values(json).reduce((acc, curr) => {
if(curr[key] === val) {
acc.push(curr);
}
return acc;
}, []);
console.log(results);
Output
[ { name: 'Rahul', age: 25 }, { name: 'Rahul', age: 35 } ]
Example-7: Perform a regex search inside JSON Object recursively
Instead of checking for an exact match of the key-value pair, we can use the RegExp.prototype.test()
method to check if the value matches the regular expression. Here's an update code which we used in previous example:
let json = {
"person1": {
"name": "Rahul",
"age": 25
},
"person2": {
"name": "Amit",
"age": 30
},
"person3": {
"name": "Ram",
"age": 35
}
}
let key = "name";
let val = /^Ra/; // regular expression
let results = Object.values(json).filter(person => val.test(person[key]));
console.log(results);
This will return an array containing the objects that have a key "name" with a value that starts with "Ra
".
Output:
[ { name: 'Rahul', age: 25 }, { name: 'Ram', age: 35 } ]
Summary
Recursive search is a powerful technique for traversing and searching complex data structures in JavaScript, such as JSON objects. By using a recursive search function, developers can easily find specific values or all values that match a certain condition within a JSON object.
In summary, recursive search is a technique for traversing a data structure and searching for an element or elements that match a specific condition. In JavaScript, this can be particularly useful when working with complex data structures such as JSON objects. By using a recursive search function, developers can easily find specific values or all values that match a certain condition within a JSON object.
References
JSON - JavaScript | MDN (mozilla.org)
Recursion - MDN Web Docs Glossary: Definitions of Web-related terms | MDN (mozilla.org)