PHP数组计数父/子


php array count parent/child

我无法正常工作。我想要的是计数器将计算每一个父级和父级内部子级这将看起来像目录,结果需要是:

<ul>
  <li><span style="color: red;">1</span>  <strong>a</strong>
  </li>
  <ul>
    <li><span style="color: red;">1.1</span>  <strong>b</strong>
    </li>
    <li><span style="color: red;">1.2</span>  <strong>c</strong>
    </li>
  </ul>
  <li><span style="color: red;">2</span>  <strong>e</strong>
  </li>
  <ul>
    <li><span style="color: red;">2.1</span>  <strong>f</strong>
    </li>
    <li><span style="color: red;">2.2</span>  <strong>g</strong>
    </li>
  </ul>
  <li><span style="color: red;">3</span>  <strong>h</strong>
  </li>
  <ul>
    <li><span style="color: red;">3.1</span>  <strong>k</strong>
    </li>
    <li><span style="color: red;">3.2</span>  <strong>l</strong>
    </li>
    <ul>
      <li><span style="color: red;">3.2.1</span>  <strong>m</strong>
      </li>
      <li><span style="color: red;">3.2.2</span>  <strong>n</strong>
      </li>
    </ul>
  </ul>
</ul>

有n个孩子那么深是无限的。我当前的代码在这里:
<?php 
$arr = array(
    array('id' => 1, 'title' => 'a', 'parent' => 0),
    array('id' => 2, 'title' => 'b', 'parent' => 1),
    array('id' => 3, 'title' => 'c', 'parent' => 1), 
    array('id' => 5, 'title' => 'e', 'parent' => 0),
    array('id' => 6, 'title' => 'f', 'parent' => 5),
    array('id' => 7, 'title' => 'g', 'parent' => 5), 
    array('id' => 8, 'title' => 'h', 'parent' => 0),
    array('id' => 9, 'title' => 'k', 'parent' => 8),
    array('id' => 10, 'title' => 'l', 'parent' => 8), 
    array('id' => 11, 'title' => 'm', 'parent' => 10), 
    array('id' => 12, 'title' => 'n', 'parent' => 10), 
);
function checkChilds($arr, $id){
    foreach ($arr as $key => $value) {
        if ($value['parent'] == $id) {
            return true;
        }
    }
    return false;
}
function getList($arr, $parent = 0, $subcounter = 1){
    $output = null;
    $output .= '<ul>';
    $counterParent = 1;
    $countChild = 1;
    foreach($arr as $key => $value) {
        if($value['parent'] == $parent){
            $counter = ($value['parent'] == 0) ? "{$counterParent}" : "{$subcounter}.{$countChild}";
            $output .= "<li><span style='color: red;'>{$counter}</span> <strong>{$value['title']}</strong></li>";
            if (checkChilds($arr, $value['id'])){
                $output .= getList($arr, $value['id'], $counterParent);
                $countChild++;
            }
            // counter for parent
            if($value['parent'] == 0) {
                $counterParent++;
            }
        }
    }
    $output .= '</ul>';
    return $output;
}
echo getList($arr);

试试这个:

<?php 
$arr = array(
    array('id' => 1, 'title' => 'a', 'parent' => 0),
    array('id' => 2, 'title' => 'b', 'parent' => 1),
    array('id' => 3, 'title' => 'c', 'parent' => 1), 
    array('id' => 5, 'title' => 'e', 'parent' => 0),
    array('id' => 6, 'title' => 'f', 'parent' => 5),
    array('id' => 7, 'title' => 'g', 'parent' => 5), 
    array('id' => 8, 'title' => 'h', 'parent' => 0),
    array('id' => 9, 'title' => 'k', 'parent' => 8),
    array('id' => 10, 'title' => 'l', 'parent' => 8), 
    array('id' => 11, 'title' => 'm', 'parent' => 10), 
    array('id' => 12, 'title' => 'n', 'parent' => 10), 
);
function checkChilds($arr, $id){
    foreach ($arr as $key => $value) {
        if ($value['parent'] == $id) {
            return true;
        }
    }
    return false;
}
function getList($arr, $parent = 0, $subcounter = 1){
    $output = null;
    $output .= '<ul>';
    $counterParent = 1;
    $countChild = 1;
    foreach($arr as $key => $value) {
        if($value['parent'] == $parent){
            $counter = ($value['parent'] == 0) ? "{$counterParent}" : "{$subcounter}.{$countChild}";
            $output .= "<li><span style='color: red;'>{$counter}</span> <strong>{$value['title']}</strong></li>";
            if (checkChilds($arr, $value['id'])){
                $output .= getList($arr, $value['id'], $counter);
            }
            $countChild++;
            // counter for parent
            if($value['parent'] == 0) {
                $counterParent++;
            }
        }
    }
    $output .= '</ul>';
    return $output;
}
echo getList($arr);

你没有传递给getList函数所有的前缀数字,只传递了直接的父值。你必须总是增加计数器,不仅仅是在需要新的getList调用时。

完整,有点简化的解决方案:

$arr = array(
    array('id' => 1, 'title' => 'a', 'parent' => 0),
    array('id' => 2, 'title' => 'b', 'parent' => 1),
    array('id' => 3, 'title' => 'c', 'parent' => 1),
    array('id' => 5, 'title' => 'e', 'parent' => 0),
    array('id' => 6, 'title' => 'f', 'parent' => 5),
    array('id' => 7, 'title' => 'g', 'parent' => 5),
    array('id' => 8, 'title' => 'h', 'parent' => 0),
    array('id' => 9, 'title' => 'k', 'parent' => 8),
    array('id' => 10, 'title' => 'l', 'parent' => 8),
    array('id' => 11, 'title' => 'm', 'parent' => 10),
    array('id' => 12, 'title' => 'n', 'parent' => 10),
);
function getList(&$arr, $level, $depth = '') {
    $count = 1;
    $ret = '<ul>';
    foreach($arr as $val) {
        if($val['parent'] === $level) {
            $ret .= '<li><span style="color: red;">' . ($depth !== '' ? $depth . '.' . $count : $count) . '</span> <strong>' . htmlentities($val['title'], ENT_COMPAT, 'UTF-8') . '</strong>';
            $ret .= getList($arr, $val['id'], $depth !== '' ? $depth . '.' . $count : $count);
            $ret .= '</li>';
            $count ++;
        }
    }
    $ret .= '</ul>';
    if($ret === '<ul></ul>') {
        return '';
    } else {
        return $ret;
    }
}
echo getList($arr, 0);
?>

请记住,这将是相当慢的大数据集。

我假设$arr是基于某种数据库驱动的数据集;

请参考这篇关于关系数据库中分层数据的文章。