【问题标题】:Convert excel column alphabet (e.g. AA) to number (e.g., 25)将excel列字母(例如AA)转换为数字(例如25)
【发布时间】:2012-04-11 22:17:06
【问题描述】:

在我的网格中,列标题被命名为A,B,C...,AA,AB,AC,...etc,就像 Excel 电子表格一样。如何将字符串转换为数字,例如:A => 1, B => 2, AA => 27

【问题讨论】:

  • 一个小修正... AA 应该是 27
  • 你不能只使用你想转换的列的位置作为它的数值吗?如果 AA 排在第 25 位,那就是你的答案……
  • 不,“没有代码 sn-p”。如果您在写一篇文章时遇到困难,请向我们展示您到目前为止所拥有的内容。对了,为什么AA是25而不是27?
  • 这是“excel 列编号”,并且已经有 SO 问题(可能不是 JavaScript)涵盖了概念和怪癖。

标签: javascript


【解决方案1】:

试试:

var foo = function(val) {
  var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;

  for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) {
    result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1);
  }

  return result;
};

console.log(['A', 'AA', 'AB', 'ZZ'].map(foo)); // [1, 27, 28, 702]

【讨论】:

    【解决方案2】:

    解决方案 1:最佳性能和浏览器兼容性

    // convert A to 1, Z to 26, AA to 27
    function lettersToNumber(letters){
        var chrs = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ', mode = chrs.length - 1, number = 0;
        for(var p = 0; p < letters.length; p++){
            number = number * mode + chrs.indexOf(letters[p]);
        }
        return number;
    }
    

    解决方案 2:最佳性能和兼容性以及更短的代码(推荐)

    // convert A to 1, Z to 26, AA to 27
    function lettersToNumber(letters){
        for(var p = 0, n = 0; p < letters.length; p++){
            n = letters[p].charCodeAt() - 64 + n * 26;
        }
        return n;
    }
    

    方案3:短代码(es6箭头函数)

    // convert A to 1, Z to 26, AA to 27
    function lettersToNumber(letters){
        return letters.split('').reduce((r, a) => r * 26 + parseInt(a, 36) - 9, 0);
    }
    

    测试:

    ['A', 'Z', 'AA', 'AB', 'ZZ','BKTXHSOGHKKE'].map(lettersToNumber);
    // [1, 26, 27, 28, 702, 9007199254740991]
    
    lettersToNumber('AAA'); //703
    

    【讨论】:

      【解决方案3】:

      下面是您应该实现的代码的快速示例。 这适用于任何给定数量的字母。

      function letterToNumbers(string) {
          string = string.toUpperCase();
          var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', sum = 0, i;
          for (i = 0; i < string.length; i++) {
              sum += Math.pow(letters.length, i) * (letters.indexOf(string.substr(((i + 1) * -1), 1)) + 1);
          }
          return sum;
      }
      

      【讨论】:

      • 您的指数有一个小错误。例如。 AB 给 53 而不是 28 与您的功能。
      • 你是对的。我修复了代码。应该是:string.substr(((i + 1) * -1), 1)
      【解决方案4】:

      我刚刚写了一个垃圾场f@#$ sn-p...需要优化.. :)

      charToNum = function(alpha) {
              var index = 0
              for(var i = 0, j = 1; i < j; i++, j++)  {
                  if(alpha == numToChar(i))   {
                      index = i;
                      j = i;
                  }
              }
              console.log(index);
          }
      
      numToChar = function(number)    {
              var numeric = (number - 1) % 26;
              var letter = chr(65 + numeric);
              var number2 = parseInt((number - 1) / 26);
              if (number2 > 0) {
                  return numToChar(number2) + letter;
              } else {
                  return letter;
              }
          }
      chr = function (codePt) {
              if (codePt > 0xFFFF) { 
                  codePt -= 0x10000;
                  return String.fromCharCode(0xD800 + (codePt >> 10), 0xDC00 + (codePt & 0x3FF));
              }
              return String.fromCharCode(codePt);
          }
      

      charToNum('A') => 返回 1 并且 charToNum('AA') => 返回 27;

      【讨论】:

      • numToChar 运行良好,但看起来您的 charToNum 函数不完整(而且效率低下)。
      • @Mark 是的,它只是一个快速的解决方法。如果可能的话,您可以优化代码并发布更好的答案。提前致谢
      【解决方案5】:

      我以更详细的形式重写了Yoshi's answer,以更好地解释它的工作原理并且更容易移植到其他语言:

      var foo = function(val) {
          var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
          var baseNumber = base.length;
      
          var runningTotal = 0;
          var characterIndex = 0;
          var indexExponent = val.length - 1;
      
          while( characterIndex < val.length ){
              var digit = val[characterIndex];
              var digitValue = base.indexOf(digit) + 1;
              runningTotal += Math.pow(baseNumber, indexExponent) * digitValue;
      
              characterIndex += 1
              indexExponent -= 1
          }
      
          return runningTotal;
      };
      
      console.log(['A', 'AA', 'AB', 'ZZ'].map(foo)); // [1, 27, 28, 702]
      

      【讨论】:

        【解决方案6】:
        // Given Column to Number
        function colToNumber(str) {
          var num = 0
          var i = 0
          while (i < str.length ) {
            num = str[i].charCodeAt() - 64 + num * 26;
            i++; 
          }
          return num;
        }
        
        //Given Number to Column name
        function numberToCol(num) {
          var str = '', q, r;    
          while (num > 0) {
            q = (num-1) / 26;
            r = (num-1) % 26
            num = Math.floor(a) 
            str = String.fromCharCode(65 + r) + str;
          }
          return str;
        }
        

        【讨论】:

        • 你试过这个吗? numberToCol 根本不起作用
        • 这是一个错字。 numberToCol 应该有“num = Math.floor(q);”。它有效!
        【解决方案7】:
        Public Function ColLet2Num(Letras As String)
        'RALONSO MAYO 2017
        'A-> 1
        'OQ ->407
        'XFD->16384
        Dim UnChar As String
        Dim NAsc As Long
        Dim F As Long
        Dim Acum As Long
        Dim Indice As Long
        Letras = UCase(Letras)
        Acum = 0
        Indice = 0
        For F = Len(Letras) - 1 To 0 Step -1
        
            UnChar = Mid(Letras, F + 1, 1)
            NAsc = Asc(UnChar) - 64
            Acum = Acum + (NAsc * (26 ^ Indice))
            Indice = Indice + 1
        Next
        If Acum > 16384 Then
            MsgBox "La celda máxima es la XFD->16384", vbCritical
        End If
        ColLet2Num = Acum
        End Function
        

        【讨论】:

          【解决方案8】:
              const getColumnName = (columnNumber) => {
                  let columnName = "";
                  const alphabets = "abcdefghijklmnopqrstuvwxyz".toUpperCase();
                  while (columnNumber > 0) {
                      const rem = columnNumber % 26;
                      if (rem === 0) {
                          columnName += "Z";
                          columnNumber = columnNumber / 26 - 1;
                      } else {
                          columnName += alphabets[rem - 1];
                          columnNumber = Math.floor(columnNumber / 26);
                      }
                  }
                  return columnName.split("").reverse().join("");
              };
          
              console.log(getColumnName(27));
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多