在CodeIgniter中递归构建数组

时间:2013-10-13 18:14:42

标签: php arrays codeigniter recursion

在CodeIgniter中我正在尝试创建一个函数。需要创建数组谁将删除db中的行,如:

$selected_items_by_id = array('1','2','3','4',);   // --<<<Need Create This
$this->db->where_in('id', $selected_items_by_id);
$this->db->delete('mytable');

mytabe 数据库结构

ID | NAME         | PARENT_ID
1   Item1              0     // First Root item
2   Item2              1     // First Root sub item
3   Item3              2     // First Root sub sub item
4   Item4              3     // First Root sub sub sub item
5   Item5              0     // Second Root item

项目布局:

Item1
+Item2
++Item3
+++Item4
Item5

这里我得到了所需的物品ID(来自选择框):

$id = $this->input->post('delete_menu_item');

逻辑:

  1. 如果项目parent_id == 0,则item为root。
  2. 如果Item是根项,则数组中只有根项id
  3. 在数组中需要$ id和所有$ id subs(如果它们存在)
  4. 更新 我试图在CI之外做出递归函数。

    搜索功能 - 分隔必要的子阵列:

     function search($array, $key, $value)
    {
        $results = array();
    
        if (is_array($array))
        {
            if (isset($array[$key]) && $array[$key] == $value)
                $results[] = $array;
    
            foreach ($array as $subarray)
                $results = array_merge($results, search($subarray, $key, $value));
        }
    
        return $results;
    }
    

    我正在使用此数组,基于数据库条目:

    $array = array(
    array('id' => '1', 'name' => 'Item1', 'parent_id' => '0'),
    array('id' => '2', 'name' => 'Item2', 'parent_id' => '1'),
    array('id' => '3', 'name' => 'Item3', 'parent_id' => '2'),
    array('id' => '4', 'name' => 'Item4', 'parent_id' => '3'),
    array('id' => '5', 'name' => 'Item5', 'parent_id' => '0'),
    );
    

    递归函数:

    function build_array($array,$id, $final = NULL){
    
    
       $data = search($array, 'id', $id);
    
       foreach ($data as $item):
           if ($item['parent_id'] == 0){
    
               $final[] = $item['id'];
    
    
           }
           else {    
               $parent_id = $item['parent_id'];
               $final[] = $item['id'];
               $final[] = $parent_id;
    
              build_array($array, $parent_id, $final); 
               // Here go recursive
           }    
       endforeach;
    
    
            return $final;
    }
    
    
    $result = build_array($array,1);
    var_dump($result);
    

    递归函数应该是什么?

3 个答案:

答案 0 :(得分:2)

如果我理解你的要求,你需要迭代地处理每个项目(循环)。

首先你得到一个项目,然后你看它是否有一个父项 - 如果是这样,得到它的父项并重新开始,等等。这是少数情况下递归函数真的可以派上用场。

你只需要随时建立你的最终数组,直到你用完项目 - 意识到如果你不小心,你会一遍又一遍地拉出相同的项目时会得到一个无限循环。

如果没有关于您需要输入什么以及想要获得什么输出的更多信息,这与任何人都可以一样有用。要获得更多帮助,您需要澄清您想要的输出,您迄今为止尝试过的代码以及您不想要的内容等等。

答案 1 :(得分:1)

确定。我将使用您放在一起的示例数组,只是略有不同:由于id是唯一的,因此没有理由不将它们作为键。像这样:

$array = array(
  '1'=>array('name' => 'Item1', 'parent_id' => '0'),
  '2'=>array('name' => 'Item2', 'parent_id' => '1'),
  '3'=>array('name' => 'Item3', 'parent_id' => '2'),
  '4'=>array('name' => 'Item4', 'parent_id' => '3'),
  '5'=>array('name' => 'Item5', 'parent_id' => '0'),
  );

将以下方法添加到您的controller / model / lib / whatever:

function children_of($arr,$id)
  {
  $r=array();
  foreach($arr as $key=>$entry)
    if($entry['parent_id']==$id) $r[]=$key;
  return $r;
  }

function subtree_array($arr,$id)
  {
  if(isset($arr[$id]))
    {
    $r=array($id);
    foreach($this->children_of($arr,$id) as $child)
      $r=array_merge($r,$this->subtree_array($arr,$child));
    return $r;
    }
  else
    return array(0); // (0) comes handy in SQL IN operations
  }

children_of()返回$id$arr直接孩子

subtree_array()返回一个数组,其中包含$id及其$arr中的所有后代。如果$id不是$arr的关键字,则返回array(0)。那是因为你说你想在SQL查询中使用它,而像where这样的where xyz in ()子句会是假的,而where xyz in (0)则不会,而且总会返回{{1}因为没有项目为零false(它似乎被保留以表示根节点)。

因此,用法可能类似于:

id

答案 2 :(得分:-2)

我试图从另一边接近任务。 使用级联删除,一切都在sql方面:

 CREATE TABLE `navigation` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(50) NOT NULL COLLATE 'utf8_general_ci',
    `url` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci',
    `position` MEDIUMINT(8) NOT NULL DEFAULT '100',
    `parent_id` INT(11) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `parent_id` (`parent_id`),
    CONSTRAINT `FK1` FOREIGN KEY (`parent_id`) REFERENCES `navigation` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB;

感谢您的建议。