PHP-функция для создания фрагментов строк возрастающей длины («fd6eg3» => «f», «fd», «fd6», «fd6eg3»)

#php #string

#php #строка

Вопрос:

tl; dr: для хранения файлов по пути, определяемому их хэшем, мне нужна одна функция, чтобы получить следующее с level=3 помощью и hash='fd6eg3' : f/fd/fd6/fd6eg3

Я ищу способ создания фрагментов (заданной строки) возрастающей длины, начиная с начала строки. Кроме того, я хочу ограничить количество создаваемых фрагментов.

Цель состоит в том, чтобы сохранить файл с именем fd6eg3 under (с количеством фрагментов, равным 3):

  • Каталог с именем fd6 .
  • Который является дочерним элементом каталога с именем fd .
  • Который является дочерним элементом каталога с именем f .

Таким образом, конечный путь будет: f/fd/fd6/fd6eg3

Самое близкое, что я получил, это получение «части каталога» ( f/fd/fd6/ ) с помощью следующей функции:

 function computePathForHash(string $hash, int $level): string
{
    if ($level <= 0) {
        return '';
    } else {
        return computePathForHash($hash, $level - 1)
            . mb_substr($hash, 0, $level)
            . DIRECTORY_SEPARATOR
        ;
    }
}
echo computePathForHash('fd6eg3', 3);
 

Какой вывод возобновляется в этой таблице:

level Возвращено
0 ""
1 "f/"
2 "f/fd/"
3 "f/fd/fd6/"

Но я не могу добавить «часть файла» ( $hash ) в конец.

Я хотел бы избежать передачи третьего параметра, такого как $initial_level , который сохранял бы первоначально запрошенный уровень, с которым я мог бы сравнить текущий $level , чтобы решить, когда добавлять $hash .

Учитывая низкое значение $level (в моем случае оно не должно превышать 10) Я не думаю, что есть аргументы против рекурсии. Я считаю, что рекурсию проще читать / понимать, но если это невозможно в рекурсии, я пойду с чем-то другим (или использую 2 функции, одну для части каталога, другую для объединения ее с файловой частью).

Комментарии:

1. С уровнем 0 просто fd6eg3 должен быть возвращен?

2. @user3783243 С помощью этой рекурсии он фактически создает строку, начиная с правой. Таким образом, если 0 бы возвращалась полная строка, она была бы в начале результата, а не в конце.

Ответ №1:

Я думаю, что рекурсия хороша в правильных обстоятельствах, но простой for цикл может сделать это и, надеюсь, более удобен в обслуживании.

Просто выполните цикл до уровня и каждый раз добавляйте начальный фрагмент хэша, а затем добавляйте полный хэш при возврате…

 function computePathForHash(string $hash, int $level): string
{
    $output = '';
    for ( $i = 1; $i <= $level; $i   )  {
        $output .= mb_substr($hash, 0, $i) . DIRECTORY_SEPARATOR;
    }
    
    return $output . $hash;
}
 

Комментарии:

1. Попробовав несколько других способов обойти рекурсию, я думаю, я преследовал что-то, что невозможно 🙂 для цикла это тогда! Примечание: я добавил небольшое ограничение на количество итераций на основе длины хэша $: $actual_level = min($level, mb_strlen($hash) - 1); и использования $actual_level вместо $level в условии for-цикла.