Хорошо, я не уверен, что это пуленепробиваемый, но я думаю, что это работает:
echo array_reduce($array, function($reducedValue, $arrayValue) {
if($reducedValue === NULL) return $arrayValue;
for($i = 0; $i < strlen($reducedValue); $i++) {
if(!isset($arrayValue[$i]) || $arrayValue[$i] !== $reducedValue[$i]) {
return substr($reducedValue, 0, $i);
}
}
return $reducedValue;
});
Это будет принимать первое значение в массиве в качестве ссылочной строки. Затем он будет перебирать ссылочную строку и сравнивать каждый символ с символом второй строки в той же позиции. Если символ не совпадает, ссылочная строка будет сокращена до позиции символа и будет сравниваться следующая строка. Затем функция вернет самую короткую подходящую строку.
Производительность зависит от заданных строк. Чем раньше строка ссылки становится короче, тем быстрее завершится код. Я действительно понятия не имею, как выразить это в формуле.
Я обнаружил, что подход Artefacto к сортировке строк повышает производительность. Добавление
asort($array);
$array = array(array_shift($array), array_pop($array));
до array_reduce
значительно увеличит производительность.
Также обратите внимание, что это вернет самую длинную подходящую исходную подстроку , которая более универсальна, но не даст вам общий путь . Вы должны запустить
substr($result, 0, strrpos($result, '/'));
на результат. И тогда вы можете использовать результат, чтобы удалить значения
print_r(array_map(function($v) use ($path){
return str_replace($path, '', $v);
}, $array));
что должно дать:
[0] => /lib/abcdedd
[1] => /conf/xyz/
[2] => /conf/abc/def
[3] => /htdocs/xyz
[4] => /lib2/abcdedd
Обратная связь приветствуется.