如何验证Map存储的车辆里程历史数据是否存在里程倒退可疑情况?
判断车辆里程历史数据是否可疑的优雅实现
问题背景
我有存储在Map中的车辆里程历史数据,结构如下:
{ "999": { created: 1698399814, // UNIX 时间戳 mileage: 120000, }, "898": { created: 1698399772, // UNIX 时间戳 mileage: 220000, } }
该Map的键为数据收集时间,值包含两个字段:
created:数据生成时间(例如:今日收集但数据实际生成于2022年)mileage:对应时刻的车辆里程数
需求是判断数据是否可疑——正常情况下里程数不应随时间倒退。比如示例中,生成时间更早的记录(created:1698399772)里程为220000,之后生成的记录里程反而变成120000,这就属于可疑数据。
我自己实现了一个可行但不够优雅的方案:
const historyArray = []; const historyMap = new Map(); historyMap.set('999', { createdAt: 1698399814, // UNIX 时间戳 mileage: 120000, }); historyMap.set('898', { createdAt: 1698399772, // UNIX 时间戳 mileage: 220000, }); for (const item of historyMap.values()) { historyArray.push(item); } const sortedA = [...historyArray].sort((a, b) => a.createdAt - b.createdAt).map((item) => item.createdAt); const sortedB = [...historyArray].sort((a, b) => a.mileage - b.mileage).map((item) => item.createdAt); const suspicious = sortedA.join() === sortedB.join()
更优雅的实现方案
可以直接按时间排序后,遍历检查里程数是否持续递增(或持平,可根据业务需求调整),逻辑更直观,性能也更优:
const historyMap = new Map(); historyMap.set('999', { createdAt: 1698399814, mileage: 120000, }); historyMap.set('898', { createdAt: 1698399772, mileage: 220000, }); // 将Map的值转为数组并按createdAt升序排序 const sortedByTime = [...historyMap.values()].sort((a, b) => a.createdAt - b.createdAt); // 遍历检查里程是否随时间递增(允许持平则用<=) let isSuspicious = false; for (let i = 1; i < sortedByTime.length; i++) { if (sortedByTime[i].mileage < sortedByTime[i-1].mileage) { isSuspicious = true; break; // 一旦发现可疑数据,直接终止遍历 } } console.log(isSuspicious); // 示例中会输出true
方案优势
- 逻辑直观:直接对应业务规则——按时间顺序检查里程是否倒退,读代码就能明白核心意图
- 性能更优:仅需一次排序+一次遍历,原方案需要两次排序、两次映射及字符串拼接对比,额外开销更大
- 可扩展性强:如果允许里程持平(比如车辆未行驶),只需修改判断条件;若需定位具体可疑记录,也能在遍历过程中直接收集相关信息
内容的提问来源于stack exchange,提问作者Andurit
相关产品推荐
相关产品推荐

