Самый простой способ состоит в использовании ссылки, например:
$out = [];
foreach ($cat as $str) {
$lookup =& $out;
foreach (explode("/", $str) as $part) {
$lookup =& $lookup[$part];
if (!isset($lookup)) {
$lookup = [];
}
}
}
$lookup
изначально относится ко всему ожидаемому результату, то ссылка продлевается на каждом шаге, чтобы следовать по пути, вложенных друг в друга элементов.
Обратите внимание, что каждый добавленный новый элемент выглядит как member-name => []
, так что фактически даже окончательные листья представляют собой массивы: это может показаться немного странным, но это прекрасный способ иметь уменьшенный код (каждый член всегда готов принять детей) ,
И это не трудность, однако, использовать полученный массив затем распечатать его как OP спросил:
function nest_print($src, $level = 0) {
$prefix = '<br />' . str_repeat('- ', ++$level);
foreach ($src as $key => $val) {
echo $prefix . $key;
if ($val) {
nest_print($val, $level);
}
}
}
nest_print($out);
EDIT
Вот альтернативное решение, в том числе подсчета из окончательных листов, по просьбе ОП в его комментарии:
$out = [];
foreach ($cat as $str) {
$lookup =& $out;
$parts = explode("/", $str);
foreach ($parts as $part) {
$lookup =& $lookup[$part];
if (!isset($lookup)) {
$lookup = [];
}
// when $part is a final leaf, count its occurrences
if ($part == end($parts)) {
$lookup = is_array($lookup) ? 1 : ++$lookup;
}
}
}
(возможно, может быть улучшено в более элегантный способ, хотя)
А вот как изменить печать результата фрагмент соответственно:
function nest_print($src, $level = 0) {
$prefix = '<br />' . str_repeat('- ', ++$level);
foreach ($src as $key => $val) {
echo $prefix . $key;
if (is_array($val)) {
nest_print($val, $level);
} else {
echo ': ' . $val;
}
}
}
nest_print($out);
Вот что я искал. Спасибо @ Томас Зима. –
Это способ узнать, сколько категорий было дубликатов? например, «Аксессуары/Ювелирные изделия/Мужчины» - в 2 раза, а массив результатов - как массив («accessories» => array («jewelery» => array («men» => 2))) –