如何在PHP中从A到Z列出,然后再到AA、AB、AC等


How to list from A to Z in PHP, and then on to AA, AB, AC, etc

我知道如何从A到Z列出:

foreach (range('A', 'Z') as $char) {
  echo $char . "'n";
}

但我该如何从那里列出AA、AB、AC、AD。。。AZ、BA、BB、BC等等?

我在谷歌上快速搜索了一下,但什么也找不到,不过我想方法会有所不同。

我想我可以通过使用for循环和一个包含字母的数组来实现,尽管这种方式看起来有点粗鲁。

还有别的办法吗?

谢谢。

PHP有一个字符串增量运算符,它可以做到这一点:

for($x = 'A'; $x < 'ZZ'; $x++)
    echo $x, ' ';

结果:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE AF... 

参考:

PHP在处理字符变量的算术运算时遵循Perl的约定,而不是C。例如,在PHP和Perl中$a='Z'$a++;将$a转换为"AA",而在C中,a="Z";a++;将a转换为"["(ASCII值"Z"为90,ASCII值"["为91)。请注意,字符变量可以递增,但不能递减,即使如此,也只支持纯ASCII字母和数字(a-Z、a-Z和0-9)。递增/递减其他字符变量无效,原始字符串不变。

http://php.net/manual/en/language.operators.increment.php

尝试

foreach (range('A', 'Z') as $char) {
    foreach (range('A', 'Z') as $char1) {
        echo $char . $char1. "'n";
    }
}

PHP在处理字符变量的算术运算时遵循Perl的约定

因此可以增加php中的字母表

$limit = "AZ";
for($x = "A", $limit++; $x != $limit; $x++) {
    echo "$x ";
}

会给你的结果

A
B
C
.
.
.
AX
AY
AZ

希望这会有所帮助。

我做了一个常数时间函数,如下

此函数提供数字索引的字母表示

public static $alpha = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
public static function getColName($index){
  $index--;
  $nAlphabets = 26;
  $f = floor($index/pow($nAlphabets,0)) % $nAlphabets;
  $s = (floor($index/pow($nAlphabets,1)) % $nAlphabets)-1;
  $t = (floor($index/pow($nAlphabets,2)) % $nAlphabets)-1;
  $f = $f < 0 ? '' : self::$alpha[$f];
  $s = $s < 0 ? '' : self::$alpha[$s];
  $t = $t < 0 ? '' : self::$alpha[$t];
  return trim("{$t}{$s}{$f}");
}

现在,如果您想使用它,请创建一个范围。您可以在循环中调用此函数,将值推送到数组中。

在大多数情况下,我们需要的是表示,而不是范围,这个函数可以很好地工作。

如何使用

只需将这些静态函数封装在一个类中,并将其用作

className::getColName(47);

在我的情况下进行测距是浪费内存

对于您的案例

for($i = 1; $i < 1000; $i++) $range[] = className::getColName($i);

正如@Abhijit Srivastava所示,但这是一种通用的方式。

function alphaIndex($index) {
    $column = "";
    $nAlphabets = 26;
    $times = (int)($index/$nAlphabets);
    $times = $index%$nAlphabets > 0 ? ($times+1):($times);
    $index--;
    for ($i=0; $i < $times; $i++) { 
        $less = $i > 0 ? 1:0;
        $key = (floor($index/pow($nAlphabets,$i)) % $nAlphabets)-$less;
        $column = ( $key<0 ? '':chr(65+$key) ).$column;
    }
    return $column;
}

我制作了一个自定义函数,该函数返回按字母顺序排列的字母范围,这些字母与通过(for example: if you set $pass=2, the function returns [A, C, E, ... AA, AC, AE])的指定数量的字母连续。

另一个有用的选项可以是$pairs=true,它将所有字母分组为成对的(for example: if you set $pairs=true, the function returns a range of consecutive groups like [[A,B],[C,D],[E,F],...[AA,AB],[AC,AD]] for $pass=1 or [[A,C],[D,F],...[AA,AC],[AD,AF]] for $pass=2)

调用示例:

$myRange = $this->AlphaRange('A','AAZ'); // returns all combinations from A to AAZ

$myRange = $this->AlphaRange('A','AAZ',2); // returns consecutive combinations from A to AAZ with letters skiped from 2 to 2

$myRange = $this->AlphaRange('A','AAZ',5,true); // returns consecutive pairs of two letters that contains first and last letter of a group of 5 letters

希望有用。

    public function AlphaRange($from, $to, $pass=1, $pairs=false) {
        $range = [];
        $currStep = 1;
        $nextStep = $pass+1;
        $currPair = 0;
        for($i=$from; $i<'ZZZ'; $i++) {
            if ($currStep == 1) {
                if (false !== $pairs) {
                    $range[$currPair][] = $i;
                }
                else {
                    $range[] = $i;
                }
            }
            else {
                if ($currStep == $nextStep) {
                    if (false !== $pairs) {
                        // $range[count($range[$currPair]) == 2 ? ++$currPair : $currPair][] = $i;
                        $range[$currPair][] = $lastI; 
                        $range[++$currPair][] = $i;
                    }
                    else {
                        $range[]  = $i;
                    }
                    $currStep = 1;
                    $nextStep = $pass+1;
                }
                else {
                    $lastI = $i;
                }                           
            }
            if ($i == $to) {
                if (false !== $pairs) {
                    if (count($range[$currPair]) == 1) {
                        $range[$currPair][] = $i;
                    }
                }
                break;
            }
            $currStep++;
        }
        return $range;
    }