基于父ID嵌套数组

时间:2014-01-11 16:35:33

标签: php arrays categories nested

我一直试图解决这个问题一周。我有一个以下格式的数组:

[
    1 => [
        'name' => 'Maths',
        'parent_category_id' => NULL
    ],
    2 => [
        'name' => 'Algebra',
        'parent_category_id' => 1
    ],
    3 => [
        'name' => 'Expanding brackets',
        'parent_category_id' => 2
    ],
    4 => [
        'name' => 'Factorising brackets',
        'parent_category_id' => 2
    ],
    5 => [
        'name' => 'English',
        'parent_category_id' => NULL
    ],
    6 => [
        'name' => 'Shakespeare',
        'parent_category_id' => 5
    ]
]

我希望将它转换为这种格式的数组:

[
    'Maths' => [
        'category_id' => 1,
        'questions' => [], //This array will then be filled with questions regarding each of the categories
        'children_categories' => [
            'Algebra' => [
                'category_id' => 2,
                'questions' => [],
                'children_categories' => [
                    'Expanding brackets' => [
                        'category_id' => 3,
                        'questions' => [],
                        'children_categories' => []
                    ],
                    'Factorising brackets' => [
                        'category_id' => 4,
                        'questions' => [],
                        'children_categories' => []
                    ]
                ]
            ]
        ]
    ],
    'English' => [
        'category_id' => 5,
        'questions' => [],
        'children_categories' => [
            'Shakespeare' => [
                'category_id' => 6,
                'questions' => [],
                'children_categories' => []
            ]
        ]
    ]
]

到目前为止,我已经能够格式化没有父母的类别,但是对于我的生活,我无法弄清楚如何将具有父级的类别插入到父级的children_categories []数组中。这是我正在使用的代码,我需要帮助弄清楚我应该放在foreach的“else”部分()

foreach($ids_as_keys as $category_id => $info){ //$info contains the name of the category, and the parent's ID (NULL if there is no parent)
    if(is_null($info['parent_category_id'])){ //There is no parent, so put it at the root of $nested
        $nested[$info['name']] = [
            'category_id' => $category_id,
            'questions' => [],
            'children_categories' => []
        ];
    }else{ //There is a parent, so search through all items (including sub-arrays, sub-sub-arrays etc.) until we find a match for the parent_category_id, and then add it into the children_categories[] array

    }
}

return $nested;

3 个答案:

答案 0 :(得分:1)

我对此进行了测试,绝对有效:

        $arr = array(
        1 => array(
            'name' => 'Maths',
            'parent_category_id' => NULL
        ),
        2 => array(
            'name' => 'Algebra',
            'parent_category_id' => 1
        ),
        3 => array(
            'name' => 'Expanding brackets',
            'parent_category_id' => 2
        ),
        4 => array(
            'name' => 'Factorising brackets',
            'parent_category_id' => 2
        ),
        5 => array(
            'name' => 'English',
            'parent_category_id' => NULL
        ),
        6 => array(
            'name' => 'Shakespeare',
            'parent_category_id' => 5
        )
    );
    foreach ($arr as $key => &$value) {
        if ($value['parent_category_id']) {
            $arr[$value['parent_category_id']]['children_categories'][] = &$value;
        }
        else{
            $parents[]=$key;
        }
    }
    $result = array();
    foreach ($parents as $val) {
        $result[$val] = $arr[$val];
    }
    print_r($result);

答案 1 :(得分:0)

这个答案太近可能对你有帮助

<?php

$array = [
    1 => [
        'name' => 'Maths',
        'parent_category_id' => NULL
    ],
    2 => [
        'name' => 'Algebra',
        'parent_category_id' => 1
    ],
    3 => [
        'name' => 'Expanding brackets',
        'parent_category_id' => 2
    ],
    4 => [
        'name' => 'Factorising brackets',
        'parent_category_id' => 2
    ],
    5 => [
        'name' => 'English',
        'parent_category_id' => NULL
    ],
    6 => [
        'name' => 'Shakespeare',
        'parent_category_id' => 5
    ]
];

//data array
$data = array();

$i = 0;

//gothrough one by one
foreach($array as $key=>$value)
{
    //set the parent array
    if(is_null($value['parent_category_id']))
    {
        $data[$value['name']]= array();
        $data[$value['name']]['category_id'] = $key;
        $data[$value['name']]['questions'] = array();
        $data[$value['name']]['children_categories'] = array();

    //add the childrens according to the parent 
    }elseif(array_key_exists($value['parent_category_id'], $array)){

        //find the parent
        $parent = $array[$value['parent_category_id']];

        $data[$parent['name']]['children_categories'][$value['name']] = array();
        $data[$parent['name']]['children_categories'][$value['name']]['category_id'] = $key;
        $data[$parent['name']]['children_categories'][$value['name']]['questions'] = array();

    }
}

//display the result
print_r($data);

答案 2 :(得分:0)

尝试使用递归函数。

function insert_child($curArr,$childArray,&$parentArray){
      foreach($parentArray as $key=>&$val){
            if(is_array($val) && sizeof($val) > 0 ){
               if($val['category_id']==$curArr['parent_category_id']){
                     $val['children_categories'][$curArr['name']] = $childArray;
                     return TRUE;        
               }else{
                 insert_child($curArr,$childArray,$val['children_categories']);
              }
             }

      }
  return FALSE;
}

$nest是您的输入数组

$nest = array(
    1=>array(
        'name' => 'Maths',
        'parent_category_id' => NULL
    ),
    2=>array(
        'name' => 'Algebra',
        'parent_category_id' => 1
    ),
    3=>array(
        'name' => 'Expanding brackets',
        'parent_category_id' => 2
    ),
    4=>array(
        'name' => 'Factorising brackets',
        'parent_category_id' => 2
    ),
    5=>array(
        'name' => 'English',
        'parent_category_id' => NULL
    ),
    6=>array(
        'name' => 'Shakespeare',
        'parent_category_id' => 5
    ),
);

$result=array();
foreach($nest as $key=>$val){
  $temp = array(
            'category_id'=>$key,
            'questions'=>array(),
            'children_categories'=>array(),
        );
  if(!in_array($val['name'],$result) && $val['parent_category_id']==NULL){
      $result[$val['name']] = $temp;
  }else{
         insert_child($val,$temp,$result);
  } 
}

echo "<pre>";
print_r($result);
exit();

PHPFIddle here