如何递归转换JS对象?解决数组被转为对象的问题
递归转换JavaScript对象时保留数组结构的解决方案
问题描述
需求是递归转换JavaScript对象:若对象仅包含label和value两个属性,则将其替换为label的值。但当前实现会把数组转换为对象,破坏原有结构。
输入对象
var input = { "general_detail_response": { "job_order_number": "J13197", "job_order_status": { "label": "Completed", "value": "COMPLETED" }, "job_order_type": null, }, "vehicle_details_response": [{ "vehicle_number": "ssssadfwdf", "vehicle_type": { "label": "Standard Trailer", "value": "STANDARD_TRAILER" }, "transporter_name": "sdfds", "shipping_details_responses": [{ "shipping_bill_number": "qwer", "metrics_break_down": { "nop": 1223, }, "exporter_name": null }], "container_details_responses": null }], "ssr_response": [{ "service_name": "22" }] };
原转换函数
function tranformFn(obj) { let output = {} for (var i in obj) { let o = obj[i]; if (o instanceof Object) { if (o.label && o.value) output[i] = o.label; else output[i] = tranformFn(o); } else output[i] = o; } return output; }
当前错误输出
{ "general_detail_response": { "job_order_number": "J13197", "job_order_status": "Completed", "job_order_type": null }, "vehicle_details_response": { "0": { "vehicle_number": "ssssadfwdf", "vehicle_type": "Standard Trailer", "transporter_name": "sdfds", "shipping_details_responses": { "0": { "shipping_bill_number": "qwer", "metrics_break_down": { "nop": 1223 }, "exporter_name": null } }, "container_details_responses": null } }, "ssr_response": { "0": { "service_name": "22" } } }
期望输出
{ "general_detail_response": { "job_order_number": "J13197", "job_order_status": "Completed", "job_order_type": null, }, "vehicle_details_response": [{ "vehicle_number": "ssssadfwdf", "vehicle_type": "Standard Trailer", "transporter_name": "sdfds", "shipping_details_responses": [{ "shipping_bill_number": "qwer", "metrics_break_down": { "nop": 1223, }, "exporter_name": null }], "container_details_responses": null }], "ssr_response": [{ "service_name": "22" }] };
问题原因
原函数存在两个核心问题:
- 未区分数组与普通对象:无论输入是数组还是对象,都初始化
output为{},导致数组被强制转为对象。 - 判断逻辑不严谨:仅检查
o.label && o.value存在,未确保对象仅包含这两个属性,可能误替换其他包含label/value的复杂对象。
修正后的转换函数
function transformFn(obj) { // 根据输入类型初始化对应结构:数组用[],对象用{} let output = Array.isArray(obj) ? [] : {}; // 数组和对象分别处理循环逻辑 if (Array.isArray(obj)) { obj.forEach((item, index) => { if (item && typeof item === 'object') { const keys = Object.keys(item); // 严格判断是否是仅含label和value的对象 if (keys.length === 2 && keys.includes('label') && keys.includes('value')) { output[index] = item.label; } else { output[index] = transformFn(item); } } else { output[index] = item; } }); } else { for (const key in obj) { if (obj.hasOwnProperty(key)) { const val = obj[key]; if (val && typeof val === 'object') { const keys = Object.keys(val); if (keys.length === 2 && keys.includes('label') && keys.includes('value')) { output[key] = val.label; } else { output[key] = transformFn(val); } } else { output[key] = val; } } } } return output; }
验证结果
调用transformFn(input)后,输出与期望完全一致:数组结构被完整保留,仅含label和value的对象被替换为label的值,其他对象、null值均保持原有形态。
内容的提问来源于stack exchange,提问作者user5711656
相关产品推荐
相关产品推荐

