修正返回错误计数的JS函数:解决计数多+1/+2问题
JavaScript统计函数计数虚高问题修复及唯一性保障
问题描述
编写的统计函数在部分场景下计数结果虚高(例如应显示1却显示2),需修复并添加唯一性保障,确保统计准确。
数据示例
[ { "currency": "USD", "services": [ { "category": [{"token": "token1"}, {"token": "token2"}], "price": 149 }, { "category": [{"token": "token3"}, {"token": "token4"}], "price": 149 } ] }, { "currency": "EUR", "services": [ { "category": [{"token": "token1"}, {"token": "token2"}], "price": 149 }, { "category": [{"token": "token3"}, {"token": "token4"}], "price": 149 } ] } ]
统计目标
按货币-价格-token的唯一组合统计token出现频率,结果按货币分组存储。
期望输出结构示例
{ "result": [ { "currency": "USD", "token": "Wellness", "count": 1, "price": 100 }, { "currency": "USD", "token": "Adventure", "count": 1, "price": 300 } ] }
当前错误代码及问题分析
错误代码
const data = inputs.data; const result = []; let error = null; try { data.forEach(item => { item.services.forEach(service => { service.category.forEach(tokenObject => { const token = tokenObject.token; const existingToken = result.find(item => item.token === token && item.price === service.price && item.currency === item.currency); if (existingToken) { existingToken.count++; } else { result.push({currency: item.currency, token, count: 1, price: service.price}); } }); }); }); } catch (e) { error = "error"; } return error ? [1, {error}] : [0, {result}]
问题根源
在result.find的判断条件中,item.currency === item.currency是同一变量的自比较,永远返回true。这导致查找时忽略了货币的匹配,只要token和价格相同就会错误累加,从而造成计数虚高。
修复方案(添加唯一性保障)
使用Map存储中间结果,通过**currency-token-price拼接的唯一键**确保每个统计组合的唯一性,避免匹配错误,同时提升查找效率:
修正后的代码
const data = inputs.data; const resultMap = new Map(); let error = null; try { data.forEach(currencyItem => { const currency = currencyItem.currency; currencyItem.services.forEach(service => { const price = service.price; service.category.forEach(tokenObj => { const token = tokenObj.token; // 生成唯一键:确保货币、token、价格三者组合唯一 const uniqueKey = `${currency}-${token}-${price}`; if (resultMap.has(uniqueKey)) { // 已存在则计数+1 resultMap.get(uniqueKey).count++; } else { // 不存在则初始化条目 resultMap.set(uniqueKey, { currency, token, count: 1, price }); } }); }); }); } catch (e) { error = "统计出错:" + e.message; } // 将Map的值转为数组,符合期望输出结构 const result = Array.from(resultMap.values()); return error ? [1, { error }] : [0, { result }];
关键改进点
- 唯一性键:用
${currency}-${token}-${price}作为Map的键,确保每个统计组合唯一,彻底避免匹配错误。 - 高效查找:Map的查找时间复杂度为O(1),比数组
find的O(n)更高效,尤其在数据量大时优势明显。 - 变量命名清晰:将嵌套循环中的
item重命名为currencyItem,避免变量名冲突,提升代码可读性。
内容的提问来源于stack exchange,提问作者Fred K
相关产品推荐
相关产品推荐

