如何用JavaScript编写函数获取列表中的缺失编号序列
JavaScript 混合序列缺失值查找实现
核心实现思路
- 先将每个序列字符串拆解为分层标识数组,区分数字、小写字母、小写罗马数字三种标识类型
- 实现三种类型与整数的双向转换,支持序列值的递增计算
- 按照分层标识对输入序列做自定义排序,保证序列顺序符合业务规则
- 遍历相邻序列项,判断是否属于同一父级前缀,若符合则计算中间所有缺失的子序列项
完整代码
// 罗马数字转整数(仅处理小写1-10,满足示例场景) function romanToInt(roman) { const map = {i:1, v:5, x:10, l:50, c:100, d:500, m:1000}; let num = 0; for (let i=0; i<roman.length; i++) { const current = map[roman[i]]; const next = map[roman[i+1]] || 0; num += current < next ? -current : current; } return num; } // 整数转小写罗马数字(仅处理1-10) function intToRoman(num) { const map = [ [10, 'x'], [9, 'ix'], [5, 'v'], [4, 'iv'], [1, 'i'] ]; let res = ''; for (const [val, sym] of map) { while (num >= val) { res += sym; num -= val; } } return res; } // 解析序列为分层数组 + 最后一级的类型 function parseSequence(str) { const reg = /^([\d.]+)(?:\(([a-z]+)\))?$/; const match = str.match(reg); if (!match) return { parts: [], type: 'num' }; const numParts = match[1].split('.').map(String); if (!match[2]) { return { parts: numParts, type: 'num' }; } const suffix = match[2]; const type = suffix.length === 1 && /[a-z]/.test(suffix) ? 'letter' : 'roman'; return { parts: [...numParts, suffix], type }; } // 计算同类型的下一个值 function getNextVal(current, type) { if (type === 'num') { return String(Number(current) + 1); } if (type === 'letter') { return String.fromCharCode(current.charCodeAt(0) + 1); } if (type === 'roman') { return intToRoman(romanToInt(current) + 1); } } // 序列自定义排序函数 function sortSequence(a, b) { const parseA = parseSequence(a); const parseB = parseSequence(b); const minLen = Math.min(parseA.parts.length, parseB.parts.length); for (let i=0; i<minLen; i++) { const partA = parseA.parts[i]; const partB = parseB.parts[i]; const isNumA = /^\d+$/.test(partA); const isNumB = /^\d+$/.test(partB); if (isNumA && isNumB) { const diff = Number(partA) - Number(partB); if (diff !== 0) return diff; } else { const diff = partA.localeCompare(partB); if (diff !== 0) return diff; } } return parseA.parts.length - parseB.parts.length; } // 主函数:查找所有缺失的序列 function findMissingSequences(inputArr) { const sorted = [...inputArr].sort(sortSequence); const missing = []; for (let i=0; i<sorted.length - 1; i++) { const curr = parseSequence(sorted[i]); const next = parseSequence(sorted[i+1]); // 只有层级长度相同、前面所有层级都相等时才判定为同层级序列 if (curr.parts.length !== next.parts.length) continue; const prefixLength = curr.parts.length - 1; let samePrefix = true; for (let j=0; j<prefixLength; j++) { if (curr.parts[j] !== next.parts[j]) { samePrefix = false; break; } } if (!samePrefix) continue; // 计算同层级中间的缺失值 const currLast = curr.parts[prefixLength]; const nextLast = next.parts[prefixLength]; let currentVal = currLast; while (true) { currentVal = getNextVal(currentVal, curr.type); if (currentVal === nextLast) break; // 拼接回原格式 let missingStr = curr.parts.slice(0, prefixLength).join('.'); if (curr.type === 'num') { missingStr += `.${currentVal}`; } else { missingStr += `(${currentVal})`; } missing.push(missingStr); } } return missing; } // 测试示例 const arr = ['1', '2', '2.1', '2.2', '2.2(a)', '2.2(b)', '2.3', '2.5', '3', '3.1', '3.2', '3.2(a)', '3.2(b)', '3.2(d)', '4', '4.1', '4.1(i)', '4.1(iii)'] console.log(findMissingSequences(arr)); // 输出:['2.4', '3.2(c)', '4.1(ii)']
扩展说明
当前代码已覆盖示例中的数字层级、小写字母后缀、小写罗马数字后缀三种场景,若需要适配更大范围的罗马数字、大写字母等规则,直接调整对应转换工具函数的逻辑即可。
内容的提问来源于stack exchange,提问作者nidhi garg
相关产品推荐
相关产品推荐

