Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Dynamic Programming: return all matched data in JavaScript
Dynamic programming in JavaScript can be used to efficiently search and retrieve data from nested structures. This article demonstrates how to search for all matching cities in a complex JSON object containing country and province information.
The Data Structure
We have a nested JSON object with countries, provinces, and cities:
const countryInfo = {
country: [{
name: "Bangladesh",
province: [{
name:"Dhaka",
city: [{
name:"Tangail",
lat: '11'
}, {
name:"Jamalpur",
lat: '12'
}]
}, {
name: "Khulna",
city: [{
name:"Jossore",
lat: '22'
}, {
name:"Tangail",
lat: '23'
}]
}, {
name: "Rajshahi",
city: [{
name:"Pabna",
lat: '33'
}, {
name:"Rangpur",
lat: '33'
}]
}]
},{
name: "India",
province: [{
name:"West Bengal",
city: [{
name:"Calcutta",
lat: '111'
}, {
name:"Tangail",
lat: '112'
}]
}, {
name: "Uttar Pradesh",
city: [{
name:"Agra",
lat: '122'
}, {
name:"Tajmahal",
lat: '123'
}]
}, {
name: "Rajasthan",
city: [{
name:"Kanpur",
lat: '131'
}, {
name:"Jaypur",
lat: '132'
}]
}]
}]
};
console.log("Data structure loaded successfully");
Data structure loaded successfully
The Search Function
Our function uses dynamic programming principles to flatten the nested structure and then filter for matching cities:
const searchForCity = (obj, query) => {
// First, extract all cities using reduce to flatten the structure
const cities = obj.country.reduce((acc, val) => {
val.province.forEach(el => {
el.city.forEach(elm => {
acc.push(elm);
});
});
return acc;
}, []);
// Filter cities that match the query
const res = cities.filter(el => {
return el.name === query;
});
return res;
};
// Test the function
console.log("Searching for 'Tangail':");
console.log(searchForCity(countryInfo, 'Tangail'));
Searching for 'Tangail':
[
{ name: 'Tangail', lat: '11' },
{ name: 'Tangail', lat: '23' },
{ name: 'Tangail', lat: '112' }
]
How It Works
The function operates in two phases:
-
Flattening Phase: Uses
reduce()to traverse all countries and provinces, collecting all city objects into a single array -
Filtering Phase: Uses
filter()to return only cities matching the search query
Alternative Implementation with Better Performance
For better performance, we can avoid creating the intermediate array and directly filter while traversing:
const searchForCityOptimized = (obj, query) => {
const results = [];
obj.country.forEach(country => {
country.province.forEach(province => {
province.city.forEach(city => {
if (city.name === query) {
results.push(city);
}
});
});
});
return results;
};
// Test optimized version
console.log("Optimized search for 'Tangail':");
console.log(searchForCityOptimized(countryInfo, 'Tangail'));
Optimized search for 'Tangail':
[
{ name: 'Tangail', lat: '11' },
{ name: 'Tangail', lat: '23' },
{ name: 'Tangail', lat: '112' }
]
Case-Insensitive Search
To make the search more flexible, we can implement case-insensitive matching:
const searchForCityInsensitive = (obj, query) => {
const results = [];
const lowerQuery = query.toLowerCase();
obj.country.forEach(country => {
country.province.forEach(province => {
province.city.forEach(city => {
if (city.name.toLowerCase() === lowerQuery) {
results.push(city);
}
});
});
});
return results;
};
// Test case-insensitive search
console.log("Case-insensitive search for 'tangail':");
console.log(searchForCityInsensitive(countryInfo, 'tangail'));
Case-insensitive search for 'tangail':
[
{ name: 'Tangail', lat: '11' },
{ name: 'Tangail', lat: '23' },
{ name: 'Tangail', lat: '112' }
]
Comparison of Methods
| Method | Memory Usage | Performance | Features |
|---|---|---|---|
| Original (reduce + filter) | Higher | Good | Functional approach |
| Optimized (direct iteration) | Lower | Better | Memory efficient |
| Case-insensitive | Lower | Better | Flexible matching |
Conclusion
Dynamic programming techniques in JavaScript help efficiently search nested data structures. The key is to flatten or traverse the structure systematically and apply filtering logic to return all matching results.
