JS按索引生成递增字母函数异常:索引超26无法生成AA/AB等
问题:生成序列英文字母键合并对象失败
需要将对象数组合并为单个对象,要求对象的键为英文字母序列(A-Z之后依次为AA、AB、AC...)。自行编写的incrementLetter函数接收索引数字并返回对应字母,但索引超过26后始终返回AA,无法生成AB等后续字母。
原代码如下:
function incrementLetter(charIndex) { const letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let value = letter.charAt(charIndex); let carry = 1; let res = ""; for (let i = value.length - 1; i >= 0; i--) { let char = value.toUpperCase().charCodeAt(i); char += carry; if (char > 90) { char = 65; carry = 1; } else { carry = 0; } res = String.fromCharCode(char) + res; if (!carry) { res = value.substring(0, i) + res; break; } } if (carry) { res = "A" + res; } return res; } const dataSource =[{"column_name":"id"},{"column_name":"group_name"},{"column_name":"date_lol"},{"column_name":"aaaasdccc"},{"column_name":"created_table_at"},{"column_name":"test_bro"},{"column_name":"ddddd"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"}] const addKeyLetter = (data) => { const mapped = data.map((item, i) => ({ [incrementLetter(i -1)]: item.column_name, })); const object = Object.assign({}, ...mapped); console.log(object); }; addKeyLetter(dataSource);
期望输出:
{ "A": "id", "B": "group_name", "C": "date_lol", "D": "aaaasdccc", "E": "created_table_at", "F": "test_bro", "G": "ddddd", "H": "ddddda", "I": "ddddda", "J": "ddddda", "K": "ddddda", "L": "ddddda", "M": "ddddda", "N": "ddddda", "O": "ddddda", "P": "ddddda", "Q": "ddddda", "R": "ddddda", "S": "ddddda", "T": "ddddda", "U": "ddddda", "V": "ddddda", "W": "ddddda", "X": "ddddda", "Y": "ddddda", "Z": "ddddda", "AA": "ddddda", "AB": "ddddda" }
解决方案
原函数的核心问题是逻辑错误:它把输入的索引当成单个字符的位置,然后对该字符做+1自增操作,这完全不符合“索引对应字母序列”的需求(比如索引26应该直接对应AA,而不是把Z加1得到AA)。正确的逻辑应该是将索引转换为无0的26进制数(A对应1,B对应2...Z对应26,AA对应27)。
修正后的代码如下:
// 修正后的字母生成函数 function getLetterFromIndex(index) { const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let result = ""; // 因为索引从0开始(对应A),所以先+1转为1-based let num = index + 1; while (num > 0) { // 计算当前位的偏移,注意要减1因为没有0 const remainder = (num - 1) % 26; result = letters.charAt(remainder) + result; num = Math.floor((num - 1) / 26); } return result; } const dataSource =[{"column_name":"id"},{"column_name":"group_name"},{"column_name":"date_lol"},{"column_name":"aaaasdccc"},{"column_name":"created_table_at"},{"column_name":"test_bro"},{"column_name":"ddddd"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"},{"column_name":"ddddda"}] const addKeyLetter = (data) => { const mapped = data.map((item, i) => ({ // 直接传入索引i,无需i-1 [getLetterFromIndex(i)]: item.column_name, })); const object = Object.assign({}, ...mapped); console.log(object); }; addKeyLetter(dataSource);
修正说明:
- 逻辑调整:将索引转为1-based的数值,通过循环取余和整除26的方式生成字母序列,完全匹配Excel列名的生成规则。
- 调用简化:原代码中
incrementLetter(i-1)的i-1是错误的,修正后直接传入i即可(索引0对应A,1对应B...26对应AA)。 - 结果准确:运行后会生成符合预期的字母键,超过26的索引会正确生成AA、AB等序列。
内容的提问来源于stack exchange,提问作者Anik Ahmed fathe
相关产品推荐
相关产品推荐

