如何从复杂对象中提取所有匹配结构的地址数据?
从嵌套JSON中提取所有符合Address结构的对象
这种在复杂嵌套的JSON里,不管字段叫什么名字,只要结构符合就把它捞出来的需求,我之前做项目的时候也碰到过,确实挺头疼的——用hasOwnProperty只能查当前层的键,lodash的filter又搞不定深层嵌套的情况。不过用递归遍历+结构校验的方式就能优雅解决,给你分享下具体实现:
核心思路
- 先写一个校验函数,判断某个对象是不是符合我们要的Address结构(不管它的父字段叫什么)
- 再写一个递归遍历函数,把整个JSON对象的每个层级都扫一遍,遇到符合结构的对象就收集起来
具体代码实现
1. 定义Address结构校验函数
首先得明确什么是符合要求的Address:根据你的示例,它需要包含houseNo(字符串)、city(字符串),还有一个包含code和name(都是字符串)的country对象。我们就基于这个写校验逻辑:
function isAddress(obj) { // 先排除非对象和null的情况 if (!obj || typeof obj !== 'object') return false; // 逐一校验必要字段的类型和结构 return ( typeof obj.houseNo === 'string' && typeof obj.city === 'string' && obj.country && typeof obj.country === 'object' && typeof obj.country.code === 'string' && typeof obj.country.name === 'string' ); }
如果你的实际场景里有可选字段,比如street可能不是必填的,直接调整这里的判断条件就行,非常灵活。
2. 递归遍历并收集地址
接下来写递归函数,遍历整个JSON的所有层级,包括数组(如果你的数据里有数组的话也能处理):
function extractAddresses(obj, results = []) { // 如果是数组,遍历每个元素递归处理 if (Array.isArray(obj)) { obj.forEach(item => extractAddresses(item, results)); return results; } // 非对象直接跳过 if (!obj || typeof obj !== 'object') return results; // 检查当前对象是不是地址,是就加入结果数组 if (isAddress(obj)) { results.push(obj); } // 遍历当前对象的所有值,继续递归深层结构 Object.values(obj).forEach(value => extractAddresses(value, results)); return results; }
3. 测试示例数据
把你给的示例JSON丢进去测试:
const sampleData = { "user": { "firstName": "John", "lastName": "Steve", "address": { "houseNo": "24", "city": "CA", "country": { "code": "US", "name": "United States" } } }, "employee": { "employeeID": "443434", "employeeName": "Steve", "employeeAddress": { "houseNo": "244", "city": "NJ", "country": { "code": "US", "name": "United States" } } }, "assistant": { "assitantID": "443434", "employeeName": "Steve", "shippingDetails": { "shippingAddress": { "houseNo": "2444", "city": "LA", "country": { "code": "US", "name": "United States" } } } } }; const allAddresses = extractAddresses(sampleData); console.log(allAddresses); // 输出结果会包含三个符合结构的地址对象
为什么这个方案更优雅?
- 不依赖字段名:不管地址字段叫
address、employeeAddress还是shippingAddress,只要结构对就会被提取 - 全层级覆盖:递归遍历能处理任意深度的嵌套结构,哪怕地址藏在好几层对象里面
- 灵活可扩展:校验函数可以根据实际业务需求随时调整,比如增加可选字段、修改字段类型校验
内容的提问来源于stack exchange,提问作者Apps
相关产品推荐
相关产品推荐

