用PHP获取数组的相对最低3层

e0bqpujr  于 2023-02-28  发布在  PHP
关注(0)|答案(2)|浏览(113)

我有一个PHP数组中的项目列表,我正在尝试编写一个函数来获取每个数组块中相对最低3个级别的值。我可以基于parent_id字段来分层格式化数组,但现在我只想过滤到相对最低3个级别。
下面是我正在使用的数组(值只是示例):

array (
  0 => 
  array (
    'id' => 1,
    'parent_id' => NULL,
    'name' => 'Home',
    'children' => 
    array (
      0 => 
      array (
        'id' => 3,
        'parent_id' => 1,
        'name' => 'Contact',
        'children' => 
        array (
          0 => 
          array (
            'id' => 6,
            'parent_id' => 3,
            'name' => 'Phone',
          ),
          1 => 
          array (
            'id' => 7,
            'parent_id' => 3,
            'name' => 'Email',
          ),
        ),
      ),
    ),
  ),
  1 => 
  array (
    'id' => 2,
    'parent_id' => NULL,
    'name' => 'About',
    'children' => 
    array (
      0 => 
      array (
        'id' => 4,
        'parent_id' => 2,
        'name' => 'History',
      ),
      1 => 
      array (
        'id' => 5,
        'parent_id' => 2,
        'name' => 'Team',
        'children' => 
        array (
          0 => 
          array (
            'id' => 8,
            'parent_id' => 5,
            'name' => 'John',
            'children' => 
            array (
              0 => 
              array (
                'id' => 12,
                'parent_id' => 8,
                'name' => 'John 2',
              ),
            ),
          ),
          1 => 
          array (
            'id' => 10,
            'parent_id' => 5,
            'name' => 'Alex',
          ),
        ),
      ),
    ),
  ),
  2 => 
  array (
    'id' => 9,
    'parent_id' => 22,
    'name' => 'Mary',
  ),
)

我尝试编写的PHP函数应该会产生以下输出:

      • 关于**
  • 历史
  • 团队
  • 约翰
      • 家**
  • 接触
    • 电话 *
    • 电子邮件 *
      • 玛丽**

对于真实数据,可能有更多或更少的级别,因此函数应该能够找到最低级别,无论只有4个级别(如本例所示)还是12个级别。
我可以写一个函数来返回数组的前3层,但是我正在寻找一个好的方法来返回每个数组块的后3层。
提前感谢您的帮助!

    • 其他背景**

PHP中的原始数组:

$flat_array = array(
    array('id' => 1, 'parent_id' => null, 'name' => 'Home'),
    array('id' => 2, 'parent_id' => 1, 'name' => 'About'),
    array('id' => 3, 'parent_id' => 1, 'name' => 'Contact'),
    array('id' => 4, 'parent_id' => 2, 'name' => 'History'),
    array('id' => 5, 'parent_id' => 2, 'name' => 'Team'),
    array('id' => 6, 'parent_id' => 3, 'name' => 'Phone'),
    array('id' => 7, 'parent_id' => 3, 'name' => 'Email'),
    array('id' => 8, 'parent_id' => 5, 'name' => 'John'),
    array('id' => 9, 'parent_id' => 11, 'name' => 'Mary'),
);

我把它转换成一个层次数组的函数是:

function hierarchyOrder($flat_array) {
    $resultIds = get_ids(($flat_array));
    $map = array();
    foreach ($flat_array as $arr) {
        $map[$arr['id']] = $arr;
    }
    $hierarchy = array();
    foreach ($flat_array as $arr) {
        if (($arr['parent_id'] !== null) AND (in_array($arr["parent_id"], $resultIds))) {
            $map[$arr['parent_id']]['children'][] = &$map[$arr['id']];
        }
        else {
            $hierarchy[] = &$map[$arr['id']];
        }
    }
    return $hierarchy;
}

function get_ids($flat_array) {
    return array_map(function($item) {
      return $item['id'];
    }, $flat_array);
}

以前,我尝试通过修改一个返回数组前3层的类似函数来构建函数。我的解决方案不够动态,并且我无法找到一个可靠地返回后3层的逻辑。我的出发点是:

function returnCorrectLevels($input) {
  $result = [];

  foreach ($input as $item) {
      $level1 = [
          'id' => $item['id'],
          'parent_id' => $item['parent_id'],
          'name' => $item['name'],
      ];

      if (isset($item['children'])) {
          $level2 = [];
          foreach ($item['children'] as $child1) {
              $level2[] = [
                  'id' => $child1['id'],
                  'parent_id' => $child1['parent_id'],
                  'name' => $child1['name'],
              ];

              if (isset($child1['children'])) {
                  $level3 = [];
                  foreach ($child1['children'] as $child2) {
                      $level3[] = [
                          'id' => $child2['id'],
                          'parent_id' => $child2['parent_id'],
                          'name' => $child2['name'],
                      ];
                  }
                  $level2[count($level2)-1]['children'] = $level3;
              }
          }
          $level1['children'] = $level2;
      }
      $result[] = $level1;
  }
  return $result;
}
z31licg0

z31licg01#

最初,根据问题中提到的所需输出,About菜单项的parent_id必须为null

<?php 
// Base array to arrange
$flat_array = array(
    array('id' => 1, 'parent_id' => null, 'name' => 'Home'),
    array('id' => 2, 'parent_id' => null, 'name' => 'About'),
    array('id' => 3, 'parent_id' => 1, 'name' => 'Contact'),
    array('id' => 4, 'parent_id' => 2, 'name' => 'History'),
    array('id' => 5, 'parent_id' => 2, 'name' => 'Team'),
    array('id' => 6, 'parent_id' => 3, 'name' => 'Phone'),
    array('id' => 7, 'parent_id' => 3, 'name' => 'Email'),
    array('id' => 8, 'parent_id' => 5, 'name' => 'John'),
    array('id' => 9, 'parent_id' => 11, 'name' => 'Mary'),
);

// Obtaining hierarchy order used from existing question
function hierarchyOrder($flat_array) {

    // Getting all parent IDs from the array
    $resultIds = get_ids(($flat_array));
   
    // empty output array 
    $map = array();

    // iterating through to get array elements
    foreach ($flat_array as $arr) {
        $map[$arr['id']] = $arr;
    }
    
    // Blank output array
    $hierarchy = array();

    // Iterating through $flat_array to get child elements
    foreach ($flat_array as $arr) {
        if (($arr['parent_id'] !== null) AND (in_array($arr["parent_id"], $resultIds))) {
            $map[$arr['parent_id']]['children'][] = &$map[$arr['id']];
        }
        else {
            $hierarchy[] = &$map[$arr['id']];
        }
    }
    
    return $hierarchy;
}

// function to get parent IDs 
function get_ids($flat_array) {
    return array_map(function($item) {
      return $item['id'];
    }, $flat_array);
}

//  assigning the final result to a variable
$result = hierarchyOrder($flat_array);
?>
<ul>
    <?php foreach($result as $item){
        echo "<li><strong>{$item['name']}</strong>";
        if(isset($item['children']) AND count($item['children']) > 0)
        {
            echo "<ul>";
                foreach($item['children'] as $child)
                {
                    echo "<li>{$child['name']}";
                    if(isset($child['children']) AND count($child['children']) > 0)
                    {
                        echo "<ul>";
                        foreach($child['children'] as $subchild)
                        {
                            echo "<li>{$subchild['name']}</li>";
                        }
                        echo "</ul>";
                    }
                    echo "</li>";
                }
            echo "</ul>";
        }
        echo "</li>";
    }?>
</ul>

最终产出如下:
Screenshot of final output as desired

在阅读了作者的评论后编辑

<?php 
// Base array to arrange
$flat_array = array(
    array('id' => 1, 'parent_id' => null, 'name' => 'Home'),
    array('id' => 2, 'parent_id' => null, 'name' => 'About'),
    array('id' => 3, 'parent_id' => 1, 'name' => 'Contact'),
    array('id' => 4, 'parent_id' => 2, 'name' => 'History'),
    array('id' => 5, 'parent_id' => 2, 'name' => 'Team'),
    array('id' => 6, 'parent_id' => 3, 'name' => 'Phone'),
    array('id' => 7, 'parent_id' => 3, 'name' => 'Email'),
    array('id' => 8, 'parent_id' => 5, 'name' => 'John'),
    array('id' => 9, 'parent_id' => 11, 'name' => 'Mary'),
    array('id' => 10, 'parent_id' => 8, 'name' => 'Kiran'),
);

// Obtaining hierarchy order used from existing question
function hierarchyOrder($flat_array) {

    // Getting all parent IDs from the array
    $resultIds = get_ids(($flat_array));
   
    // empty output array 
    $map = array();

    // iterating through to get array elements
    foreach ($flat_array as $arr) {
        $map[$arr['id']] = $arr;
    }
    
    // Blank output array
    $hierarchy = array();

    // Iterating through $flat_array to get child elements
    foreach ($flat_array as $arr) {
        if (($arr['parent_id'] !== null) AND (in_array($arr["parent_id"], $resultIds))) {
            $map[$arr['parent_id']]['children'][] = &$map[$arr['id']];
        }
        else {
            $hierarchy[] = &$map[$arr['id']];
        }
    }
    
    return $hierarchy;
}

// function to get parent IDs 
function get_ids($flat_array) {
    return array_map(function($item) {
      return $item['id'];
    }, $flat_array);
}

//  assigning the final result to a variable
$result = hierarchyOrder($flat_array);

// function to generate menu items - recursively
function prepare_menu_items($menuArray)
{
    $output = '';
    foreach($menuArray as $item){
        $output .= "<li>{$item['name']}";
        if(isset($item['children']) AND count($item['children']) > 0)
        {
            $output .= "<ul>";
            $output .= prepare_menu_items($item['children']);
            $output .= "</ul>";
        }
        $output .= "</li>";
    }
    
    return $output;
}

?>
<ul>
    <?=prepare_menu_items($result)?>
</ul>

上面的代码容纳n数量的级别,对于当前给出的示例,挑选底部3个级别有点挑战性。
如果数组是从下到上递减排列的,你可以尝试正排列。你可以按照我下面的评论来尝试。

yshpjwxd

yshpjwxd2#

好吧我来修

$flat_array = array(
array('id' => 1, 'parent_id' => null, 'name' => 'Nikos Kontominas'),
array('id' => 2, 'parent_id' => null, 'name' => 'Ioanna Kontominas'),
array('id' => 3, 'parent_id' => 1, 'name' => 'Panagiotis Kontominas'),
array('id' => 4, 'parent_id' => 2, 'name' => 'George Filipakos'),
array('id' => 5, 'parent_id' => 2, 'name' => 'Katina Filipakos'),
array('id' => 6, 'parent_id' => 3, 'name' => 'Nikos Kontominas'),
array('id' => 7, 'parent_id' => 3, 'name' => 'Elpida Kontominas'),
array('id' => 8, 'parent_id' => 5, 'name' => 'John Travolta'),
array('id' => 9, 'parent_id' => null, 'name' => 'Mary Kontominas'),
array('id' => 10, 'parent_id' => 7, 'name' => 'Katia Gianakakos'),
array('id' => 11, 'parent_id' => 10, 'name' => 'Elpida Hover'),
);

 ///////////////////////////
echo '<ul>';
returbData($flat_array);
echo '</ul>';
function returbData($arr){
$record=count($arr);    
 foreach ($arr as $item) {
    if($item['parent_id']==null){
        echo '<li>'.$item['name'];
        repeat($item['id'],$arr);
        }
    }
  }


  function repeat($item,$arr){
  echo'<ul>';
   foreach ($arr as $parent) {
    if($item==($parent['parent_id'])){
        
        echo '<li>'.$parent['name'];
        
        repeat($parent['id'],$arr);
      }
   }
   echo '</ul>';
   echo '</li>';    

}

并且您有输出页面代码

<ul>
<li>Nikos Kontominas
    <ul><li>Panagiotis Kontominas
        <ul><li>Nikos Kontominas
            <ul></ul>
            </li>
            <li>Elpida Kontominas
                <ul><li>Katia Gianakakos
                    <ul><li>Elpida Hover
                        <ul></ul>
                        </li>
                    </ul>
                    </li>
                </ul>
            </li>
        </ul>
        </li>
    </ul>
</li>
<li>Ioanna Kontominas
    <ul><li>George Filipakos
            <ul></ul>
        </li>
        <li>Katina Filipakos
            <ul><li>John Travolta
                <ul></ul>
                </li>
            </ul>
        </li>
    </ul>
</li>
<li>Mary Kontominas
    <ul></ul>
</li>

相关问题