代码说

code is poetry

代码说    
碎碎念:开放留言!在文章页内容最后,点击“留言”按钮,就可以留言了。  换一换

二维数组中的排序问题

作者:coderzheng 发布于:2015-12-15 0:39 Tuesday 分类:php  阅读模式

来看一个实际的排序案例:
<?php
$arr = array(
     '23' => array('a'=>'000','v'=>21),
     '31' => array('a'=>'12q','v'=>19),
     '12' => array('a'=>'er','v'=>20),
     '24' => array('a'=>'mn','v'=>10),
     '11' => array('a'=>'kl','v'=>16),
     '10' => array('a'=>'kk','v'=>17),
     '9' => array('a'=>'mP','v'=>18),
     '8' => array('a'=>'mn0','v'=>19),
     '1' => array('a'=>'mn1','v'=>10),
     '3' => array('a'=>'mn2','v'=>9),
     '2' => array('a'=>'mn3','v'=>21),
     '4' => array('a'=>'mn4','v'=>16),
     '6' => array('a'=>'mn5','v'=>17),
     '5' => array('a'=>'mn6','v'=>20),
     '7' => array('a'=>'mn7','v'=>10),
     '22' => array('a'=>'mn8','v'=>18),
     '13' => array('a'=>'mn9','v'=>9),
     '14' => array('a'=>'xnt','v'=>14),
);
现在要求对上面这个数组按照二维键为v的值进行排序。比如观察上面的数组可知,排序后二维数组应该按下面的顺序输出:
array(
     0=>array('a'=>'000','v'=>21,),
     1=>array('a'=>'mn3','v'=>21,),
     2=>array('a'=>'er','v'=>20,),
     3=>array('a'=>'mn6','v'=>20,),
     4=>array('a'=>'12q','v'=>19,),
     ...
)
下面是完整的程序,来看一下代码:
<?php
$arr = array(
     '23' => array('a'=>'000','v'=>21),
     '31' => array('a'=>'12q','v'=>19),
     '12' => array('a'=>'er','v'=>20),
     '24' => array('a'=>'mn','v'=>10),
     '11' => array('a'=>'kl','v'=>16),
     '10' => array('a'=>'kk','v'=>17),
     '9' => array('a'=>'mP','v'=>18),
     '8' => array('a'=>'mn0','v'=>19),
     '1' => array('a'=>'mn1','v'=>10),
     '3' => array('a'=>'mn2','v'=>9),
     '2' => array('a'=>'mn3','v'=>21),
     '4' => array('a'=>'mn4','v'=>16),
     '6' => array('a'=>'mn5','v'=>17),
     '5' => array('a'=>'mn6','v'=>20),
     '7' => array('a'=>'mn7','v'=>10),
     '22' => array('a'=>'mn8','v'=>18),
     '13' => array('a'=>'mn9','v'=>9),
     '14' => array('a'=>'xnt','v'=>14),
);

function sort_arr($arr) {
     $range = array();
     foreach ($arr as $v) {
          $range[] = $v['v'];
     }
     rsort($range);
     $indexArr = array();
     foreach($range as $k=>$v) {
          $indexArr[$v][] = $k;
          $indexArr[$v]['index'] = 0;
     }
     return $indexArr;
}

$indexArr = sort_arr($arr); // 已经排序的索引数组

$list = array();
foreach ($arr as $v) {
     $val = $v['v'];
     $index = $indexArr[$val]['index'];
     $indexArr[$val]['index']++;
     $indexr = $indexArr[$val][$index];
     $list[$indexr] = $v;
}
ksort($list);
print_r($list);
exit;
来仔细分析一下:sort_arr函数直接对目标值进行了信息提取的工作,来看一下这个信息数组长什么样:
我们看到,这个信息数组把所有目标值作为键名存在了一个新数组中,每个键名对应的键值实际上就是我们在构建新数组时需要存储的必要信息。比如上图中21对应的子数组array([0]=>0,[1]=>1,[index]=>0),意思是,在新数组中值为21的部分,存储在新数组中的数字索引为0和1,其中index对应的是当前要存储的数字索引(没存储之前都是0,理所应当从0开始)。这样,这个信息数组构造完成之后,后面的工作实际上就很简单了:重新遍历一次原来初始的数组,根据之前构造的信息数组,计算目标排序值在新数组中对应的数字索引,直接存储起来就好了。需要注意的是,这样重新构造之后,新数组的数字索引不是从小到大排列的,因此必须重新使用ksort函数进行排序。
PS:上面的算法忽略了原二维排序数组中对键值(即23,31,12,24,11,10...)的保存,这里我们给出的简单方案是:添加键值对。即在原来的子数组中多加一个键值对来保存这个键值。处理之后,新得到的数组直接简化了信息展示的复杂度,一般都能满足实际要求。这里不再展示具体操作的代码,请读者自行思考。




============== 全文完 ================

标签: 疑难杂症 算法

你可以发表评论、引用到你的网站或博客,或通过RSS 2.0订阅这个博客的所有文章。
上一篇: 从分页类到ACL  |  下一篇:被Jquery坑了