无限分级的实现

作者: 我不是鱼 (2008-10-27 16:50)分类: PHP   标签: 无限分级

之前面试的时候碰到过这个问题,没有能回答出来。今天搜集了一些资料,总结了一下就记了下来,应该以后还要上。顺便也和大家讨论下。

PHP代码
  1. <?php    
  2. $arr = array(   
  3.     array('id'=>1, 'pid'=>0, 'order'=>0),   
  4.     array('id'=>2, 'pid'=>0, 'order'=>1),   
  5.     array('id'=>3, 'pid'=>2, 'order'=>0),   
  6.     array('id'=>4, 'pid'=>0, 'order'=>2),   
  7.     array('id'=>5, 'pid'=>3, 'order'=>0),   
  8.     array('id'=>6, 'pid'=>1, 'order'=>0),   
  9.     array('id'=>7, 'pid'=>1, 'order'=>1)   
  10. );   
  11.   
  12. function order($a,$b) {   
  13.     if($a['pid'] == $b['pid']) {   
  14.         if($a['order'] > $b['order'])   
  15.             return 1;   
  16.         elseif($a['order'] < $b['order'])    
  17.             return -1;   
  18.         return 0;   
  19.     }   
  20.        
  21.     return $a['pid'] > $b['pid'] ? 1 : -1;   
  22. }   
  23.   
  24. usort($arr"order");   
  25.   
  26. $new_arr = array();   
  27. $temp_arr = array();   
  28.   
  29. foreach($arr as $row) {   
  30.     $row['child'] = array();   
  31.     if($row['pid'] == 0) {   
  32.         $i = count($new_arr);   
  33.         $new_arr[$i] = $row;   
  34.         $temp_arr[$row['id']] = &$new_arr[$i];   
  35.     }   
  36.     else {   
  37.         $i = count($temp_arr[$row['pid']]['child']);   
  38.         $temp_arr[$row['pid']]['child'][$i] = $row;   
  39.         $temp_arr[$row['id']] = &$temp_arr[$row['pid']]['child'][$i];   
  40.     }   
  41. }   
  42.   
  43. echo "<pre>", print_r($new_arr, true), "</pre>";   
  44. ?>   


$arr就是要分级的数据,id是自身唯一的id。pid是指父节点的id,其中0是最高分级。order就是排列顺序,分级相同时按order排序。order函数是为 usort 排序提供的排序函数,如果对 usort 不太理解,可以参考下 http://www.phpfans.net/bbs/PHPfunction.php?function=usort order函数对同级别的根据order值排序,不同级别的父节点在子节点前面。避免先出现子节点再出现父节点。
$new_arr是用了保存分级后的数据,$temp_arr用来保存临时的数据。
好了,下面来看一下这个排列的过程。$row['child'] 是用来保存比当前分级更低级别的数据,如果$row['child']为空,则当前没有更低分级。当 $row['pid'] == 0 时,即使最高级别,直接保存到 $new_arr 数组。其中下面这步是非常关键的:$temp_arr[$row['id']] = &$new_arr[$i]; 这个和一般的赋值 $temp_arr[$row['id']] = $new_arr[$i]; 不同,注意 &。这个是传引用。php中的传引用和c中的传址是一样的效果。如果大家不好理解,下面我举个例子大家就易于明白了。

PHP代码
  1. <?php   
  2. $arr = array(1, 2, 3);   
  3. $new_arr = &$arr;   
  4. $new_arr[] = 4;   
  5. print_r($new_arr);   
  6. print_r($arr);   
  7. ?>   

可以看到现在 $new_arr 和 $arr 都是 array(1, 2, 3, 4)。也就是说接下来我们改变 $temp_arr[$row['id']] 的值,$new_arr[$i]也会跟着改变。

order函数排序后pid为0的排在最前面,foreach循环会现将pid为0的级别保存到$new_arr:$new_arr[$i] = $row;并通过传引用赋值给$temp_arr:$temp_arr[$row['id']] = &$new_arr[$i]; $temp_arr的索引是$row自身的id。
当 $row['pid'] != 0 时,也就是该分级有父节点,该父节点的id就应该等于该分级的pid。我们要做的是将该分级$row保存到父节点的 child 数组里。而我们现在可以通过改变 $temp_arr[$row['pid']] 的值达到这样效果:$temp_arr[$row['pid']]['child'][$i] = $row;同样将该分级的值引用赋值给$temp_arr:$temp_arr[$row['id']] = &$temp_arr[$row['pid']]['child'][$i];以便该级别的子节点对该级别的child进行赋值。循环过后就已经讲数据分级好了。

评论 (0) | 浏览 (4507)

前一篇: 今天自己的blog要开通了
后一篇: Apache 虚拟机设置


添加评论

昵称:


博主


« 2020年-12月 »
29 30 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 1 2

分类


热门标签


最近留言


概要

  • 文章数量: 41
  • 分类数量: 9
  • 标签数量: 73
  • 评论数量: 159
  • 浏览次数: 3236523

友情链接