罗马数字转换器返回undefined值问题求助
罗马数字转换器返回undefined值问题求助
我仔细看了你的代码,发现你遇到的undefined问题主要是两个核心原因:罗马数字映射列表的结构设计不对,还有数组操作的逻辑绕了弯路且有误,咱们一步步来调整修复:
问题1:lettersList的结构错误
你现在把每一位的罗马数字放在了单独的对象里(比如{0: ['', 'I', ...]}),但实际上你需要的是一个二维数组——外层数组的索引对应位数(0=个位,1=十位,2=百位,3=千位),内层数组的索引对应数字(0-9),直接返回对应的罗马字符。
原来的结构中,当你用lettersList[i][deletedItem[0]]时,lettersList[i]是一个对象,而对象里并没有deletedItem[0](比如数字3)这个键,所以自然返回undefined。
修正后的lettersList应该是这样:
const lettersList = [ ['', 'I','II','III','IV','V', 'VI', 'VII', 'VIII', 'IX'], // 个位(索引0) ['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'], // 十位(索引1),开头加空字符串对应数字0的情况 ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'], // 百位(索引2) ['', 'M', 'MM', 'MMM'] // 千位(索引3) ]
问题2:数组操作逻辑冗余且错误
你用splice反复删除插入元素的思路太绕了,其实可以更简单:直接遍历拆分后的数字位,把每一位对应的罗马字符收集到新数组里,最后反转拼接成正确顺序即可。
原来的代码中,inputList.splice(i, 1,)这种写法本身就有语法问题,而且反复修改原数组很容易导致索引混乱。
修复后的完整代码
<!-- 假设你的HTML基础结构如下 --> <input type="number" id="number" placeholder="输入1-3999的数字"> <button id="convert-btn">转换</button> <div id="output" hidden></div> <script> const output = document.getElementById("output"); const number = document.getElementById('number'); const convertBtn = document.getElementById('convert-btn'); const lettersList = [ ['', 'I','II','III','IV','V', 'VI', 'VII', 'VIII', 'IX'], ['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'], ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'], ['', 'M', 'MM', 'MMM'] ]; const makeNum = (input) => { output.removeAttribute("hidden"); const inputValue = parseInt(input.value); // 转成数字,避免字符串比较的潜在问题 let result = []; if (inputValue > 3999) { output.innerHTML = '<p>Please enter a number less than or equal to 3999</p>'; return; // 提前退出,避免无效逻辑执行 } else if (inputValue < 1 || isNaN(inputValue)) { // 新增非数字输入的判断 output.innerHTML = '<p>Please enter a number greater than or equal to 1 </p>'; return; } // 拆分数字的每一位,比如123拆成3(个位)、2(十位)、1(百位) let num = inputValue; let digitIndex = 0; // 对应lettersList的索引(0=个位) while (num > 0) { const digit = num % 10; // 取当前个位数字 result.push(lettersList[digitIndex][digit]); // 收集对应罗马字符 num = Math.floor(num / 10); // 去掉已处理的个位数字 digitIndex++; } // 反转数组并拼接,得到正确顺序的罗马数字 const romanNumeral = result.reverse().join(''); output.innerHTML = `<p>${romanNumeral}</p>`; }; convertBtn.addEventListener("click", () => { makeNum(number); }); </script>
关键调整说明
- 先把输入值转成数字
parseInt(input.value),避免字符串和数字比较的潜在bug(比如字符串"10000"和数字3999比较会出问题)。 - 用
while循环拆分每一位数字,比操作字符串数组更直观,也避免了索引混乱。 - 收集每一位对应的罗马字符后,反转数组再拼接,就能得到正确顺序的罗马数字。
- 增加了
isNaN判断,处理用户输入非数字的情况。
现在你测试一下,输入123应该得到CXXIII,输入3999得到MMMCMXCIX,输入4得到IV,都能正常工作啦~
备注:内容来源于stack exchange,提问作者conmanh01
相关产品推荐
相关产品推荐

