JavaScript中如何校验JSON正整数、逐行打印错误数组及预校验水果数量
问题梳理与实现逻辑修正
核心待解决问题
- 校验错误存入数组后,需要在console中逐行打印,但当前用
join('\n')拼接打印的方式会把数组转为纯字符串,丢失数组原有结构,无法支持后续对错误项的独立处理(如错误计数、类型分类) - 水果数量校验逻辑顺序倒置:当前实现是先累加所有同类型水果的数值,再校验累加结果是否为整数,会出现单条记录为小数(如1.5)、累加后刚好为整数(两个1.5相加为3)的漏判场景,不符合“单条水果数量必须为正整数(仅整果)”的要求
- 字段保留要求:JSON字段顺序不固定,需要独立存储weight、苹果总数量、香蕉总数量三个字段供后续函数调用,不能因为校验流程导致字段可访问性失效
原有实现的具体缺陷
- weight字段校验逻辑漏洞:使用
Math.sign(weightData)判断数字合法性的方式存在隐式类型转换问题,传入非数字字符串时返回NaN,判断逻辑完全失效 - 水果校验时机错误:先执行reduce逻辑累加所有水果数量,再对累加后的总值做整数校验,完全跳过了单条记录的数值合法性检查,直接放过单条为小数的违规数据
- 错误数组存储冗余:校验时把空字符串占位存入错误数组,最后拼接打印时会输出无意义的空行,且拼接操作破坏了数组本身的结构
修正后的实现步骤
- 初始化独立的业务字段存储对象和错误列表对象,不随JSON原始字段顺序变动影响字段获取
- 前置执行单条数据校验:遍历水果数组的每一条记录,先校验单条amount是否为大于0的正整数,校验不通过直接推入错误数组,不参与后续累加
- 错误数组仅存储非空的错误信息,不存入占位空字符串
- 逐行打印错误时不破坏数组结构:通过遍历数组的每一项单独调用console.log,实现逐行输出的效果,同时保留数组本身的类型和方法能力供后续调用
修正后的可运行代码
'use strict'; // 接收到的原始JSON数据 const receivedData = { age: 'twenty', // 对应需求中的weight字段,仅允许合法数字 fruits: [ { type: 'banana', amount: 5 }, { type: 'apple', amount: 1.5 }, // 违规:单条为小数,非整果 { type: 'banana', amount: 2 }, { type: 'banana', amount: 1.5 }, // 违规:单条为小数,非整果 { type: 'apple', amount: 2 }, ], }; // 初始化独立存储结构:保留需要供后续调用的字段,独立维护错误列表 const businessData = { weight: null, totalApple: 0, totalBanana: 0, }; const errorList = []; // 校验weight字段合法性 const weightRaw = receivedData.age; if (typeof weightRaw !== 'number' || Number.isNaN(weightRaw)) { errorList.push(`weight值 ${weightRaw} 不是合法数字`); } else { businessData.weight = weightRaw; } // 先逐行校验单条水果记录,合法值才做累加 const fruitsList = receivedData.fruits || []; fruitsList.forEach((item, index) => { const { type, amount } = item; // 单条校验规则:必须是大于0的正整数 const isValidAmount = typeof amount === 'number' && !Number.isNaN(amount) && amount > 0 && amount % 1 === 0; if (!isValidAmount) { errorList.push(`第${index + 1}条水果记录的数量 ${amount} 不是合法整果数`); return; } // 合法值累加 if (type === 'apple') businessData.totalApple += amount; if (type === 'banana') businessData.totalBanana += amount; }); // 逐行打印错误,完全保留errorList的数组结构 errorList.forEach(err => console.log(err)); // 独立业务字段可直接传入后续函数使用 console.log('可调用的独立业务字段:', businessData);
内容的提问来源于stack exchange,提问作者C3PO
相关产品推荐
相关产品推荐

