如何高效提取嵌套JSON中的指定字段?
从嵌套JSON中提取特定字段并整理为数组
问题场景
从API获取到嵌套JSON数据后,需要提取三类值并整理为数组:
termType为GIVENNAME的string值termType为SURNAME的string值gender字段的值
示例JSON数据
{ "matches":[ { "parsedPerson":{ "personType":"NATURAL", "personRole":"PRIMARY", "mailingPersonRoles":[ "ADDRESSEE" ], "gender":{ "gender":"MALE", "confidence":0.9325842696629214 }, "addressingGivenName":"Brandyn", "addressingSurname":"Kramer", "outputPersonName":{ "terms":[ { "string":"Brandyn", "termType":"GIVENNAME" }, { "string":"Kramer", "termType":"SURNAME" } ] } }, "parserDisputes":[], "likeliness":0.9427026792672768, "confidence":0.9433333333333334 } ], "bestMatch":{ "parsedPerson":{ "personType":"NATURAL", "personRole":"PRIMARY", "mailingPersonRoles":[ "ADDRESSEE" ], "gender":{ "gender":"MALE", "confidence":0.9325842696629214 }, "addressingGivenName":"Brandyn", "addressingSurname":"Kramer", "outputPersonName":{ "terms":[ { "string":"Brandyn", "termType":"GIVENNAME" }, { "string":"Kramer", "termType":"SURNAME" } ] } }, "parserDisputes":[], "likeliness":0.9427026792672768, "confidence":0.9433333333333334 } }
当前遇到的问题
- 直接通过
var gender = data.bestMatch.parsedPerson.gender.gender取值不够灵活,希望用批量处理方式整理成数组 - 尝试提取
GIVENNAME的代码返回undefined,原代码如下:
const findName = (obj, key) => { const arr = obj['outputPersonName']; if(arr.length){ const result = arr.filter(el => { return el['termType'] === key; }); if(result && result.length){ return result.string; } else{ return ''; } } } console.log(findName(data.parsedPerson, 'GIVENNAME'));
解决方案
先分析错误原因
你写的findName函数有两个核心问题:
obj['outputPersonName']是对象而非数组,arr.length会直接报错,实际要操作的是obj.outputPersonName.terms数组filter方法返回的是匹配元素组成的数组,不能直接用result.string,需要提取数组内每个元素的string属性
完整批量处理实现(覆盖matches和bestMatch)
如果需要提取所有匹配项和最佳匹配的数据,可以用循环批量处理:
// 假设data是从API获取的JSON数据 const data = {/* 你的JSON数据 */}; // 初始化结果数组 const Given = []; const Surname = []; const gender = []; // 处理matches数组中的每个项 data.matches.forEach(item => { const person = item.parsedPerson; // 提取gender person.gender?.gender && gender.push(person.gender.gender); // 提取姓名分类 person.outputPersonName.terms.forEach(term => { if (term.termType === 'GIVENNAME') Given.push(term.string); else if (term.termType === 'SURNAME') Surname.push(term.string); }); }); // 处理bestMatch项 const bestPerson = data.bestMatch.parsedPerson; bestPerson.gender?.gender && gender.push(bestPerson.gender.gender); bestPerson.outputPersonName.terms.forEach(term => { if (term.termType === 'GIVENNAME') Given.push(term.string); else if (term.termType === 'SURNAME') Surname.push(term.string); }); // 可选:去重避免重复数据 const uniqueGiven = [...new Set(Given)]; const uniqueSurname = [...new Set(Surname)]; const uniqueGender = [...new Set(gender)]; console.log('Given Names:', uniqueGiven); // ["Brandyn"] console.log('Surnames:', uniqueSurname); // ["Kramer"] console.log('Genders:', uniqueGender); // ["MALE"]
简化版(仅处理bestMatch)
如果只需要提取最佳匹配的数据,可以简化代码:
const bestPerson = data.bestMatch.parsedPerson; const Given = bestPerson.outputPersonName.terms .filter(term => term.termType === 'GIVENNAME') .map(term => term.string); const Surname = bestPerson.outputPersonName.terms .filter(term => term.termType === 'SURNAME') .map(term => term.string); const gender = [bestPerson.gender.gender]; console.log(Given); // ["Brandyn"] console.log(Surname); // ["Kramer"] console.log(gender); // ["MALE"]
修复你的findName函数
如果想保留函数式写法,修复后的版本如下:
const findName = (obj, key) => { // 先检查必要字段是否存在,避免报错 if (!obj?.outputPersonName?.terms) return []; // 过滤目标类型并提取string值 return obj.outputPersonName.terms .filter(el => el.termType === key) .map(el => el.string); }; // 使用示例 const givenNames = findName(data.bestMatch.parsedPerson, 'GIVENNAME'); const surnames = findName(data.bestMatch.parsedPerson, 'SURNAME'); console.log(givenNames); // ["Brandyn"] console.log(surnames); // ["Kramer"]
内容的提问来源于stack exchange,提问作者EagleEye
相关产品推荐
相关产品推荐

