将数字转换为26个字符以外的字母
Convert numbers to letters beyond the 26 character alphabet
我正在为可映射的电子表格导出功能创建一些客户端函数。
我使用jQuery来管理列的排序顺序,但每个列都像Excel电子表格一样排序,即a b c de ......X y z aa ab ac AD等等等等
如何生成一个数字作为一个字母?我应该定义一个固定的值数组吗?或者是否有一种动态的方式来生成它?
我想你在找这样的东西
function colName(n) {
var ordA = 'a'.charCodeAt(0);
var ordZ = 'z'.charCodeAt(0);
var len = ordZ - ordA + 1;
var s = "";
while(n >= 0) {
s = String.fromCharCode(n % len + ordA) + s;
n = Math.floor(n / len) - 1;
}
return s;
}
// Example:
for(n = 0; n < 125; n++)
document.write(n + ":" + colName(n) + "<br>");
这是一个非常简单的方法:
function numberToLetters(num) {
let letters = ''
while (num >= 0) {
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[num % 26] + letters
num = Math.floor(num / 26) - 1
}
return letters
}
function getColumnDescription(i) {
const m = i % 26;
const c = String.fromCharCode(65 + m);
const r = i - m;
return r > 0
? `${getColumnDescription((r - 1) / 26)}${c}`
: `Column ${c}`
}
用法:
getColumnDescription(15)
"Column P"
getColumnDescription(26)
"Column AA"
getColumnDescription(4460)
"Column FOO"
简单递归解:
function numberToColumn(n) {
const res = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[n % 26];
return n >= 26 ? numberToColumn(Math.floor(n / 26) - 1) + res : res;
}
如果你的数据是一个二维数组,例如
var data = [
['Day', 'score],
['Monday', 99],
];
您可以将行/列映射到电子表格单元格编号,如下所示(基于上面的代码示例构建):
function getSpreadSheetCellNumber(row, column) {
let result = '';
// Get spreadsheet column letter
let n = column;
while (n >= 0) {
result = String.fromCharCode(n % 26 + 65) + result;
n = Math.floor(n / 26) - 1;
}
// Get spreadsheet row number
result += `${row + 1}`;
return result;
};
。数据[0][0]中的"日"值将放在电子表格单元格A1中。
> getSpreadSheetCellNumber(0, 0)
> "A1"
这也适用于当你有26+列:
> getSpreadSheetCellNumber(0, 26)
> "AA1"
您可以像这样使用代码,假设numbers
包含您的列数。在这段代码之后,您将得到列的字符串名称:
var letters = ['a', 'b', 'c', ..., 'z'];
var numbers = [1, 2, 3, ...];
var columnNames = [];
for(var i=0;i<numbers.length;i++) {
var firstLetter = parseInt(i/letters.length) == 0 ? '' : letters[parseInt(i/letters.length)];
var secondLetter = letters[i%letters.length-1];
columnNames.push(firstLetter + secondLetter);
}
这里有一种依赖于.toString(26)
的替代方法。它使用转换到26进制,然后将字符转换为a..z
范围:
const conv = ((base, alpha) => { // Closure for preparing the function
const map = Object.fromEntries(Array.from(alpha, (c, i) => [c, alpha[i + 10]]));
return n => (n + base).toString(26).replace(/o*p/, "").replace(/./g, m => map[m]);
})(parseInt("ooooooooop0", 26), "0123456789abcdefghijklmnopqrstuvwxyz");
// Example:
for (let n = 0; n < 29; n++) console.log(n, conv(n));
console.log("...");
for (let n = 690; n < 705; n++) console.log(n, conv(n));
关于神奇数字
魔法值"ooooooooop0"导出如下:
- 这是一个以基数26表示的数字,以标准的方式表示,即10位数字也起作用,然后是字母表的第一个字母。
- 最伟大的"数字";在这个基数中,26是& & & &;(拉丁字母中的16第个字母),以及"是第二大的。
- 这个神奇的值是由一个足够长的序列组成的,这个序列由一个但最大的数字组成,后面跟着一个最大的数字,最后以0结尾。
- 由于JavaScript的整数在
Number.MAX_SAFE_INTEGER
附近最大(更大的整数将遭受舍入错误),因此不需要有更长的一系列" 0 "他被选中了。我们可以看到Number.MAX_SAFE_INTEGER.toString(26)
有12位数字,因此以26为基数确保精度高达11位,这意味着我们需要9 " 0 "。 - 这个神奇的数字确保了如果我们给它加单位(以基数26为单位),我们将总是得到一个以一系列"0"开头的表示。然后是"& & & &"。这是因为在某一时刻,最后一位数字又会转到0,而"& & &;"也会绕到0,将前面的"o"p"帮助"。所以我们有了这个不变量数字总是以0或大于0开始;然后是& & &;
更通用的
上面的幻数可以通过代码得到,我们可以通过提供目标字母表来使它更通用。目标字母表的长度也直接决定了基数(即该字符串中的字符数)。
下面是与上面相同的输出,但使用了更通用的函数:function createConverter(targetDigits) {
const radix = targetDigits.length,
alpha = "0123456789abcdefghijklmnopqrstuvwxyz",
map = Object.fromEntries(Array.from(alpha,
(src, i) => [src, targetDigits[i]]
)),
base = parseInt((alpha[radix-1]+'0').padStart(
Number.MAX_SAFE_INTEGER.toString(radix).length - 1, alpha[radix-2]
), radix),
trimmer = RegExp("^" + alpha[radix-2] + "*" + alpha[radix-1]);
return n => (n + base).toString(radix)
.replace(trimmer, "")
.replace(/./g, m => map[m]);
}
// Example:
const conv = createConverter("abcdefghijklmnopqrstuvwxyz");
for (let n = 0; n < 29; n++) console.log(n, conv(n));
console.log("...");
for (let n = 690; n < 705; n++) console.log(n, conv(n));
现在可以很容易地调整为使用更精简的目标字母(例如不使用字母"l")和" 0 "),给出24的基数,而不是26:
function createConverter(targetDigits) {
const radix = targetDigits.length,
alpha = "0123456789abcdefghijklmnopqrstuvwxyz",
map = Object.fromEntries(Array.from(alpha,
(src, i) => [src, targetDigits[i]]
)),
base = parseInt((alpha[radix-1]+'0').padStart(
Number.MAX_SAFE_INTEGER.toString(radix).length - 1, alpha[radix-2]
), radix),
trimmer = RegExp("^" + alpha[radix-2] + "*" + alpha[radix-1]);
return n => (n + base).toString(radix)
.replace(trimmer, "")
.replace(/./g, m => map[m]);
}
// Example without "l" and "o" in target alphabet:
const conv = createConverter("abcdefghijkmnpqrstuvwxyz");
for (let n = 0; n < 29; n++) console.log(n, conv(n));
console.log("...");
for (let n = 690; n < 705; n++) console.log(n, conv(n));
范围从1到1000。除此之外我没有检查过。
function colToletters(num) {
let a = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (num < 27) return a[num % a.length];
if (num > 26) {
num--;
let letters = ''
while (num >= 0) {
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[num % 26] + letters
num = Math.floor(num / 26) - 1
}
return letters;
}
}
我可能错了,但我检查了这个答案中的其他函数,它们似乎在26处失败,应该是Z.记住字母表中有26个字母,而不是25个。
相关文章:
- 如何为jQuery屏蔽输入插件创建一个允许字母数字、空格和重音字符的掩码
- 带静态字符e输入的文本框数字和带javascript的负整数
- 使用正则表达式匹配长度为六个字符的字母数字字符串
- 删除图形和数字之间的连字符(-)符号
- 如何限制一个字段只接受4个数字字符作为输入,并获得'It’这是潜水警报
- 为什么这个正则表达式不't匹配最后一个字母数字字符
- 一个jquery验证器方法,它不接受纯数字或纯特殊字符,但接受上面是否有字母
- node.js可以识别字符模式,但不能识别数字模式
- 如何使用至少一个数字、一个大写字母和6-20个字符验证密码
- Javascript Regex选择每个非字母数字字符和空白
- Javascript中的正则表达式,用于只有数字的字符串,并且不应在除数字以外的任何位置包含任何字符
- JavaScript正则表达式(带_-的字母数字字符)
- 忽略任何非小写字符(如数字、大写字母和符号)并获取k的值
- 为什么Javascript中的整数加空格加字符串会导致数字和字符串的总和?(2++'22'=24)
- 在粘贴事件Javascript的输入字段中删除所有非数字字符
- JavaScript-Regex删除代码/特殊字符/数字等
- JavaScript:仅按字符或按字符+数字(如果存在)拆分字符串
- jQuery中的“#”字符(数字符号)是什么意思?
- 正则表达式,用于替换任何字符(数字/、.除外)
- jQuery tokeninput插件,当返回1字符数字的结果时出现问题