JavaScript Reducer函数中对象字段出现Undefined问题排查
问题描述
我正在学习扩展运算符(spread operators)、reducer函数及通用数据处理方法。借助Stack Overflow的帮助,我实现了一个可按日期筛选出带ID的最新评估数据的函数,原本运行正常。但我为评估对象新增cadence和assessmentName字段后,结果中这两个字段显示为Undefined,请问问题出在哪里?
代码示例
const result = data.map(({assessments, ...rest}) => ({ ...rest, 'assessments' : Object.entries(assessments .reduce((a, [{ id, date }]) => { a[id] = (a[id] || '').localeCompare(date) > 0 ? a[id] : date return a }, {})) .map(([id, date, cadence, assessmentName]) => ([{ id, date, cadence, assessmentName }])) })) console.log(result)
数据示例
const data = [ { "partnerId": "p0001", "partnerName": "Foo", "assessments": [ [ { "id": "a0016", "date": "2021-03-20", "cadence": "Annual", "assessmentName": "FFIEC CAT Survey" } ], [ { "id": "a0016", "date": "2021-11-19", "cadence": "Annual", "assessmentName": "FFIEC CAT Survey" } ], [ { "id": "a0011", "date": "2022-05-19", "cadence": "Annual", "assessmentName": "FCC Risk Assessment" } ], [ { "id": "a0011", "date": "2020-10-29", "cadence": "Annual", "assessmentName": "FCC Risk Assessment" } ], [ { "id": "a0001", "date": "2021-11-30", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments" } ], [ { "id": "a0001", "date": "2022-06-07", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments" } ], [ { "id": "a0013", "date": "2022-01-20", "cadence": "Annual", "assessmentName": "FL Risk Assessment" } ] ] }, { "partnerId": "p0002", "partnerName": "Bar", "assessments": [ [ { "id": "a004", "date": "2021-03-20", "cadence": "Semi-Annual", "assessmentName": "Model Governance" } ], [ { "id": "a003", "date": "2021-11-19", "cadence": "Quarterly", "assessmentName": "Credit Strategy" } ], [ { "id": "a003", "date": "2022-05-19", "cadence": "Quarterly", "assessmentName": "Credit Strategy" } ], [ { "id": "a003", "date": "2020-10-29", "cadence": "Quarterly", "assessmentName": "Credit Strategy" } ], [ { "id": "a0001", "date": "2021-11-30", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments" } ], [ { "id": "a0001", "date": "2022-06-07", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments" } ], [ { "id": "a0013", "date": "2022-01-20", "cadence": "Annual", "assessmentName": "FL Risk Assessment" } ] ] } ]
问题原因
你的reduce阶段只存储了date字符串,没有保留cadence和assessmentName这些额外字段。原来的逻辑里,a[id]仅存储日期值,后续Object.entries只能拿到id和date两个元素,所以解构cadence和assessmentName时自然会得到undefined。
修复方案
需要在reduce时存储完整的评估对象,而非仅保留日期。通过对比对象中的date字段来保留最新数据,这样就能完整保留所有需要的字段:
const result = data.map(({ assessments, ...rest }) => ({ ...rest, assessments: Object.values(assessments .reduce((acc, [assessment]) => { // 对比当前存储对象与新对象的日期,保留最新的那个 if (!acc[assessment.id] || new Date(assessment.date) > new Date(acc[assessment.id].date)) { acc[assessment.id] = assessment; } return acc; }, {})) // 保持原数据的嵌套数组结构(每个评估包裹在数组中) .map(assessment => [assessment]) })); console.log(result);
修复说明
reduce中接收完整的assessment对象,不再仅解构id和date- 使用
new Date()对比日期,比localeCompare更直观可靠(ISO格式日期字符串也可直接用字符串比较,但Date对象逻辑更清晰) - 用
Object.values直接获取最新评估对象数组,比Object.entries再解构更简洁 - 最后通过
map将每个对象包裹进数组,保持原数据的嵌套结构
内容的提问来源于stack exchange,提问作者mediaguru
相关产品推荐
相关产品推荐

