两种对象数组型JSON结构解析与取值undefined问题排查
JSON字段取值异常问题解决
问题现象
当前处理两类对象数组结构的JSON数据时,现有遍历逻辑可在第一套模拟数据上正常运行,在第二套模拟数据中执行rest.CustomerName取值时始终返回undefined。
测试数据源
第一套模拟数据(Mock Data One)
[ { "key": "row-0", "cells": [ { "key": "cell-0", "id": "ID-0", "headerName": "Name", "CustomerName": "CR One", "CustomerID": "P-01", "CustomerNumber": "123456789" } ] }, { "key": "row-1", "cells": [ { "key": "cell-1", "id": "ID-1", "headerName": "Name", "CustomerName": "CR Two", "CustomerID": "P-02", "CustomerNumber": "123456789" } ] }, { "key": "row-2", "cells": [ { "key": "cell-2", "id": "ID-2", "headerName": "Name", "CustomerName": "CR Three", "CustomerID": "P-03", "CustomerNumber": "123456789" } ] }, { "key": "row-3", "cells": [ { "key": "cell-3", "id": "ID-3", "headerName": "Name", "CustomerName": "CR Four", "CustomerID": "P-04", "CustomerNumber": "123456789" } ] }, { "key": "row-4", "cells": [ { "key": "cell-4", "id": "ID-4", "headerName": "Name", "CustomerName": "CR Five", "CustomerID": "P-05", "CustomerNumber": "123456789" } ] } ]
第二套模拟数据(Mock Data Two)
[ { "key":"row-0", "cells":[ {"key":"cell-0","id":"ID-0","headerName":"customerName","customerName":"Customer One"}, {"key":"cell-1","id":"ID-1","headerName":"CustomerRegID","CustomerRegID":"C-01"}, {"key":"cell-2","id":"ID-2","headerName":"CustomerNumber","CustomerNumber":"1234567890"}, {"key":"cell-3","id":"ID-3","headerName":"CustomerLabel","CustomerLabel":["Reg","Temp"]} ] }, {"key":"row-1", "cells":[ {"key":"cell-0","id":"ID-0","headerName":"customerName","customerName":"Customer Two"}, {"key":"cell-1","id":"ID-1","headerName":"CustomerRegID","CustomerRegID":"C-02"}, {"key":"cell-2","id":"ID-2","headerName":"CustomerNumber","CustomerNumber":"1234567890"}, {"key":"cell-3","id":"ID-3","headerName":"CustomerLabel","CustomerLabel":["Reg","Temp"]} ] }, {"key":"row-2", "cells":[ {"key":"cell-0","id":"ID-0","headerName":"customerName","customerName":"Customer Three"}, {"key":"cell-1","id":"ID-1","headerName":"CustomerRegID","CustomerRegID":"C-03"}, {"key":"cell-2","id":"ID-2","headerName":"CustomerNumber","CustomerNumber":"1234567890"}, {"key":"cell-3","id":"ID-3","headerName":"CustomerLabel","CustomerLabel":["Reg","Temp"]} ] }, {"key":"row-3", "cells":[ {"key":"cell-0","id":"ID-0","headerName":"customerName","customerName":"Customer Four"}, {"key":"cell-1","id":"ID-1","headerName":"CustomerRegID","CustomerRegID":"C-04"}, {"key":"cell-2","id":"ID-2","headerName":"CustomerNumber","CustomerNumber":"1234567890"}, {"key":"cell-3","id":"ID-3","headerName":"CustomerLabel","CustomerLabel":["Reg","Temp"]} ] }, {"key":"row-4", "cells":[ {"key":"cell-0","id":"ID-0","headerName":"customerName","customerName":"Customer Five"}, {"key":"cell-1","id":"ID-1","headerName":"CustomerRegID","CustomerRegID":"C-05"}, {"key":"cell-2","id":"ID-2","headerName":"CustomerNumber","CustomerNumber":"1234567890"}, {"key":"cell-3","id":"ID-3","headerName":"CustomerLabel","CustomerLabel":["Reg","Temp"]} ] } ]
现有异常代码
{mockData.map((values, index) => { console.log("VALUES", values); return values.cells.map(({ headerName, ...rest }) => { console.log("JSON", JSON.stringify(rest)); console.log("REST", rest.CustomerName); // 此处始终返回undefined }); })}
问题根因
- 第一套数据结构特征:单行数据的
cells数组仅包含1个对象,所有客户相关字段(CustomerName/CustomerID/CustomerNumber)都存在这个对象中,客户名字段为大写C开头的CustomerName,硬编码取值可以正常拿到结果。 - 第二套数据结构和第一套存在两处核心差异,直接复用原有逻辑必然取值失败:
- 单行数据的
cells数组包含4个对象,每个对象仅存储1个业务字段,字段名和当前对象的headerName值完全一致,客户名、注册ID、编号、标签分属不同cell对象 - 客户名字段为小写c开头的
customerName,不存在大写开头的CustomerName字段
- 单行数据的
正确取值方案
方案1:适配第二套数据结构
第二套数据属于动态字段结构,不要硬编码字段名,先将单行的多个cell字段整合为平面对象再取值,同时兼容字段名大小写:
{mockData.map((row) => { // 整合当前行所有cell的字段为单个对象 const rowData = row.cells.reduce((result, cell) => { const { headerName } = cell; result[headerName] = cell[headerName]; return result; }, {}); // 直接从整合后的对象取值即可 const customerName = rowData.customerName; const customerRegId = rowData.CustomerRegID; const customerNumber = rowData.CustomerNumber; const customerLabel = rowData.CustomerLabel; return <div key={row.key}>{customerName}</div> })}
方案2:同时兼容两套数据结构
如果代码需要同时处理两种格式的数据,增加结构判断和字段兜底逻辑即可:
{mockData.map((row) => { let customerName = ''; // 第一套数据结构:cells长度为1,直接取对象内的名称字段 if (row.cells.length === 1) { const cell = row.cells[0]; customerName = cell.CustomerName || cell.customerName || ''; } else { // 第二套数据结构:cells长度大于1,查找客户名对应的cell再取值 const nameCell = row.cells.find(cell => cell.headerName.toLowerCase() === 'customername' ); customerName = nameCell ? (nameCell.CustomerName || nameCell.customerName || '') : ''; } return <div key={row.key}>{customerName}</div> })}
内容的提问来源于stack exchange,提问作者dev_to_be
相关产品推荐
相关产品推荐

