JS中混合罗马数字与阿拉伯数字字符串数组的排序问题
解决罗马数字与阿拉伯数字混合排序的问题
首先看你现有代码的几个核心问题:
- 数字转换逻辑失效:
Number(a)对罗马数字(比如"i")会返回NaN,而NaN != null的结果是false,所以罗马数字根本没被正确处理;而且你没有区分罗马数字和阿拉伯数字的分组,导致两类数据混在一起排序,不符合先罗马后阿拉伯的需求。 - 无意义的
position属性:字符串和数字都没有position属性,这行代码会返回NaN,直接干扰排序结果。 - 未针对罗马数字做排序适配:罗马字符串没法直接用
>或<比较大小,必须转成阿拉伯数字才能实现正确的升序排序。
要实现你的需求,我们可以分四步来完成:
- 把数组拆分为罗马数字组和阿拉伯数字组
- 实现罗马数字转阿拉伯数字的工具函数,用于罗马组的排序依据
- 分别对两组进行升序排序
- 合并排序后的罗马组和阿拉伯组
完整实现代码
var myarray = ["i", "ii", "iii", "xv", "x", "1", "2", "3", "5", "601", "vi", "vii", "88", "99", "201", "101", "xix", "125", "iv", "vi", "v", "xiv", "58"]; // 小写罗马数字转阿拉伯数字的工具函数 function romanToNum(roman) { const romanMap = { 'i': 1, 'v': 5, 'x': 10, 'l': 50, 'c': 100, 'd': 500, 'm': 1000 }; let total = 0; for (let i = 0; i < roman.length; i++) { const currentVal = romanMap[roman[i]]; const nextVal = romanMap[roman[i+1]]; // 罗马数字规则:小值在大值左侧时做减法 if (nextVal && currentVal < nextVal) { total -= currentVal; } else { total += currentVal; } } return total; } // 1. 分组:筛选罗马数字和阿拉伯数字 const romanGroup = myarray.filter(item => /^[ivxlcdm]+$/i.test(item)); const numberGroup = myarray.filter(item => /^\d+$/.test(item)); // 2. 罗马数字组排序:按转换后的数值升序,保留原字符串 romanGroup.sort((a, b) => romanToNum(a) - romanToNum(b)); // 3. 阿拉伯数字组排序:转成数字后升序,再转回字符串 numberGroup.sort((a, b) => Number(a) - Number(b)); // 4. 合并结果:罗马数字在前,阿拉伯数字在后 const sortedResult = [...romanGroup, ...numberGroup]; console.log(sortedResult);
代码说明
romanToNum函数:遵循罗马数字的标准转换逻辑,比如"iv"会被转成4,"xix"转成19,确保罗马字符串能按实际数值排序。- 分组逻辑:用正则表达式精准筛选两类数据:
/^[ivxlcdm]+$/i匹配仅含罗马字符的字符串,/^\d+$/匹配纯数字字符串。 - 排序逻辑:罗马组通过转换后的数值比较排序,阿拉伯组转成数字后比较排序,保证升序的准确性。
- 合并结果:把排序后的罗马组放在前面,阿拉伯组放在后面,完全符合你期望的排序顺序。
运行这段代码后,输出结果就是:["i","ii","iii","iv","v","vi","vi","vii","x","xiv","xv","xix","1","2","3","5","58","88","99","101","125","201","601"]
内容的提问来源于stack exchange,提问作者pr02
相关产品推荐
相关产品推荐

