JavaScript实现对象数组按点分版本号正确排序的方法
问题核心原因
你之前的方案全部失效,本质是搞错了版本号的结构:版本号是.分隔的多段独立整数,不是普通小数,也不能直接按字符串规则比较:
- 转浮点数比较时,
9.10会被解析为和9.1相等,9.11会被解析为数值9.11(数学上小于9.6),完全不符合版本号每段独立比较的要求 - 直接比较字符串时是逐字符比ASCII值,
"9.10"次版本位开头是"1",比"9.2"里的"2"ASCII值小,会被错误判定为更小 - 普通值数组的版本排序逻辑只需要调整取值逻辑就能适配对象数组,不需要冗长实现
简洁实现方案
核心逻辑是把版本号按.拆成多段数字,逐段对比数值大小即可,适配任意段数的版本号(比如1.2.3、10.0.1.2这类多段版本也能正常排序)。
升序排序(从小到大:9.2 → 9.6 → 9.10 → 9.11)
my_list.sort((a, b) => { const verA = a.xxx.split('.').map(Number); const verB = b.xxx.split('.').map(Number); // 逐段比较,找到第一个不相等的段返回差值 for (let i = 0; i < Math.max(verA.length, verB.length); i++) { const segA = verA[i] || 0; // 段数不一致时自动补0,比如9对比9.0.1时,9补为[9,0,0] const segB = verB[i] || 0; if (segA !== segB) return segA - segB; } return 0; })
降序排序(从大到小:9.11 → 9.10 → 9.6 → 9.2)
仅需要把段差值的比较顺序反转即可:
my_list.sort((a, b) => { const verA = a.xxx.split('.').map(Number); const verB = b.xxx.split('.').map(Number); for (let i = 0; i < Math.max(verA.length, verB.length); i++) { const segA = verA[i] || 0; const segB = verB[i] || 0; if (segA !== segB) return segB - segA; } return 0; })
效果验证
用上述降序方法处理你提供的测试数组,会完全符合预期输出:
[ {"xxx": "9.11", "no_of_occurrence": 1}, {"xxx": "9.10", "no_of_occurrence": 1}, {"xxx": "9.6", "no_of_occurrence": 1}, {"xxx": "9.2", "no_of_occurrence": 1} ]
如果你的业务场景里版本号固定为两段(主版本.次版本),还可以用更短的一行实现:
升序:my_list.sort((a,b) => a.xxx.split('.')[0]-b.xxx.split('.')[0] || a.xxx.split('.')[1]-b.xxx.split('.')[1])
降序:my_list.sort((a,b) => b.xxx.split('.')[0]-a.xxx.split('.')[0] || b.xxx.split('.')[1]-a.xxx.split('.')[1])
内容的提问来源于stack exchange,提问作者Kiran
相关产品推荐
相关产品推荐

