В Excel имена столбцов представляют собой символы от A до Z, если необходимо больше столбцов, они продолжаются с AA, AB ...
Я хочу написать функцию, которая преобразует целые числа в эти имена столбцов excel.
0 .... A
25 ... Z
26 ... AA
Решение, которое я придумал, работает до AZ, но я хочу, чтобы оно работало и дальше.
function indexToXlxsColumn($index, $prefix = "")
{
if ($index < 26)
{
return $prefix.chr($index+65);
}else{
return indexToXlxsColumn($index % 26, "A");
}
}
Как адаптировать эту функцию для работы для каждого индекса без создания спагетти-кода?






Вот проблема
return indexToXlxsColumn($index % 26, "A");
Вы устанавливаете префикс следующего этажа на A, что происходит, когда у вас есть input = 53 , результат должен быть "BB"
Код на бумаге
function indexToXlxsColumn($index, $prefix = "")
{
if ($index < 26) // 53 isnt less then 26
// second loop , 1 is less then 26
{
return $prefix.chr($index+65);
// $prefix = A
// chr($index+65) = B
// return "A"."B" ;
}else{
return indexToXlxsColumn($index % 26, "A");
// indexToXlxsColumn(53 % 26, "A") -> (1, "A")
}
}
---ОБНОВИТЬ---
Следите за вопросом, вот ответ
function indexToXlxsColumn($index, $suffix = "")
{
if ($index < 26){
return chr($index+65).$suffix ;
}
return indexToXlxsColumn(($index - $index%26)/26-1, chr($index%26+65).$suffix );
}
Спасибо, но я знаю, где проблема в моем коде - вопрос в том, как это исправить :D
Обновление ответа @toffler, я тоже публикую исправленный код
Спасибо - это здорово, пожалуйста, переименуйте префикс $ в суффикс $ в вашем примере, потому что ваше решение добавляет его в конец
Я бы сделал немного по другому. Мне надоело работать с chr(). Итак, однажды я сохранил алфавит в строке и перебирал его, пока индекс не был успешно разрешен.
<?php
function getIn($i) {
$str = 'abcdefghijklmnopqrstuvwxyz';
$r = (int) floor($i / 26) ;
$c = $i % 26;
return ($r) < 1 ? $str[$c] : $str[$r-1] . $str[$c];
}
echo getIn(52); // output: "ba"
function getIn($i) {
$str = 'abcdefghijklmnopqrstuvwxyz';
$r = (int) floor($i / 26);
$rr = $r >= 27 ? $r - 27 : null;
$c = $i % 26;
if ( $rr !== null) {
return $str[$c] : $str[$r-1] . $str[$c];
}
return ($r) < 1 ? $str[$c] : $str[$r-1] . $str[$c];
}
echo getIn(800); // ddu
echo getIn(1377); // zzz
Спасибо - это хорошее решение, но оно выдает предупреждение с очень большими числами: пример
@toffler Спасибо за отзыв! :-) Да, к сожалению, это решение работает только для максимального индекса 676. Но его можно расширить для больших чисел. в этой строке появляется предупреждение $r = (int) floor($i / 26) ; . Вы можете изменить здесь некоторые строки, которые функция распознает, сколько символов будет выведено. 676 только на двоих.
Я имею в виду максимальный индекс 701 = zz
Спасибо за ваше обновление, но оно просто недостаточно гибкое :), потому что если мы сделаем getIn(80000), оно больше не будет работать, и нам придется снова обновляться. + кажется, что-то не так с расчетом, потому что 800 должно быть ADU
@toffler Я подумаю после работы, чтобы сделать его более гибким. Как всегда: Спасибо за хороший вопрос! Мне было весело думать об этом :-)
Одна из реализаций:
function indexToXlxsColumn($index)
{
$name = '';
while($index > 0) {
$mod = ($index - 1) % 26;
$name = chr(65 + $mod).$name;
$index = (int)(($index - $mod) / 26);
}
return $name;
}
// echo indexToXlxsColumn(26); // Z
echo indexToXlxsColumn(33); // AG
// echo indexToXlxsColumn(800); // ADT
проверить indexToXlxsColumn (26)
это похоже на другую задачу leetCode, подобную этой -> stackoverflow.com/questions/71748484/…