0

我的帖子

个人中心

设置

  发新话题
如题,假设有张数据表,需要对其所有的字段进行排序,并生成名次,而且还要保持原来的顺序。这个在度娘上是找不到的,也没有现成的算法。

所有,只有靠自己挖脑花了~!

如图:



我们需要对学生的所有科目生成年级名次,并且保持原来的顺序。单纯地用excel排序,也要花一些时间来处理,如果用excel函数,当然也能解决,但要实现自动化,用php来实现,嘿嘿,我还真费了不少时间呢!

应用场景:很明显,就是用于对学生考试成绩的各个科目生成对应的名次。那么有没有其他的用途呢,这就要你们自己思考如何利用了哈!反正我是在我的“成绩管理系统”中用这的呢。

主类代码:
class Makesorts{
        
        private $data;
        private $error;
        
        public function __construct($data=array()){
                $this -> setData($data);
        }
        
        public function setData($data){
                $this -> data = $data;
                $this -> checkdata();
                return $this;
        }
        
        public function getData(){
                return $this -> data;
        }
        
        public function getError(){
                return $this -> error;
        }
        
        /*
                $key_arr 包含需要生成排序的键名字符串或数组
                $unkey 为真则对$key_arr的键名数组排序;为假则除$key_arr以外的进行排序
                $order='desc',默认是倒序,其他则为顺序
                $sortname 新增排序字段的键名后缀
        */
        public function makeSorts($key_arr='',$unkey=true,$order='desc',$sortname='sort'){
        
                if(!$this -> checkdata()){
                        return $this -> error;
                }
               
                $key_arr = $this -> makeKeyArr($key_arr,$unkey);
                if(!$key_arr){
                        return $this -> error;
                }
               
                foreach($key_arr as $k){
                        $arrayOne = $this -> getArrayCol($k);
                        //var_dump($arrayOne);
                        //exit;
                        
                        $arrayOneSort = $this -> makeSrot($arrayOne,$k,$order,$sortname);
                        //var_dump($arrayOneSort);
                        //exit;
                        
                        $this->data = $this -> sortArray($arrayOneSort,$k,$sortname);
                        //var_dump($this->data);
                        //exit;
                }
               
                return $this->data;
        }
        
        //检查数组是否符合格式规则
        private function checkdata(){
                //判断是否为空
                if(empty($this -> data)){
                        $this -> error = array(
                                'emptydata' => 'data is empty!',
                        );
                        return false;
                }
               
                //判断是否为非空数组
                if(is_array($this->data) and !empty($this->data)){
                        $row = $this->data[array_rand($this->data)];
                        if(!is_array($row)){
                                $this -> data = $this -> arrayOne2two($this->data);
                                $this -> error = array(
                                        'row_notice' => "your data's row is not array,but we turn it to array. Have a look function:arrayOne2two!",
                                );
                        }
                /*        else{
                                //三维数组
                                $val = $row[array_rand($row)];
                                if(is_array($val)){
                                        $this -> error = array(
                                                'val' => "your data is too deep!",
                                        );
                                        return false;
                                }
                        }
                */
                }else{
                        $this -> error = array(
                                'data' => "your data is not array or is empty!",
                        );
                        return false;
                }
               
                //检查键名一致性
                $demo = '';
                foreach($this->data as $row){
                        //if(count($row)>1){
                                $key_str = implode(',',array_keys($row));
                                if($demo === ''){
                                        $demo = $key_str;
                                }else{
                                        if($demo !== $key_str){
                                                $this -> error = array(
                                                        'chekcdata' => 'your rows keys are not same',
                                                );
                                                return false;
                                        }
                                }
                        
                /*         }else{
                                $this -> error = array(
                                        'chekcdata' => 'your data have only one row,not need to sort!',
                                );
                                return false;
                        } */
                        
                }
                return true;
        }
        
        //一维数组转二维
        private function arrayOne2two($data){
                $array = array();
                $i = 0;
                $key = array_rand($data);
                foreach($data as $val){
                        $array[$i][$key] = $val;
                        $i++;
                }
                return $array;
        }
        
        //生成将要排序的字段
        private function makeKeyArr($key_arr,$unkey){
                $all_keys = $this->getKeys();
                if($key_arr == '' || empty($key_arr)){
                        $key_arr = $all_keys;
                }
               
                if(is_string($key_arr)){
                        $key_arr = explode(',',$key_arr);
                }
               
                //排除设置的键名
                if(!$unkey){
                        $temp = array();
                        foreach($all_keys as $key){
                                if(!in_array($key,$key_arr)){
                                        $temp[] = $key;
                                }
                        }
                        $key_arr = $temp;
                }
               
                //检查键名是否存在
                foreach($key_arr as $k){
                        if(!in_array($k,$all_keys)){
                                $this -> error = array(
                                        'key' => '"' . $k . '" is a not exist key!',
                                );
                                return false;
                        }
                }
                return $key_arr;
        }
        
        //获取数组的所有键名,返回数组
        public function getKeys(){
                $k = array_rand($this -> data);
                $row = $this -> data[$k];
                return array_keys($row);
        }

        //取出要排序的那一列数组;
        private function getArrayCol($k){
                $array = array();
                foreach($this->data as $key=>$row){
                        $array[$key] = $row[$k];
                }
                return $array;
        }

        //对取出的那一列进行排序,并生成序号
        private function makeSrot($data=array(),$k,$sort,$sortname){
                if($sort == 'desc'){
                        arsort($data);
                }else{
                        asort($data);
                }
                //var_dump($data);
                $array = array();
                $i = 1;
                foreach($data as $key=>$row){
                        $array[$key][$k] = $row;
                        $array[$key][$k.$sortname] = $i++;
                }
                return $array;
               
        }

        //合并原始二维数组和已排序完成的数组
        private function sortArray($newData,$k,$newCol){
                foreach($this->data as $key=>$row){
                        $this->data[$key][$k.$newCol] = $newData[$key][$k.$newCol];
                }
                return $this->data;
        }
}
测试代码:
function test(){
        $data = array(        //符合规则的数组
                array('id'=>1,'name'=>'aa','age'=>33,'ch'=>'啊'),
                array('id'=>3,'name'=>'bb','age'=>11,'ch'=>'才'),
                array('id'=>2,'name'=>'cc','age'=>22,'ch'=>'不'),
        );
        $data2 = array(        //符合规则的数组,内部自动转换成二维数组
                4,2,1,3
        );
        $data3 = array(        //符合规则的数组:随机取一个键名作为排序索引键
                'id'=>'1','name'=>'aa','age'=>'33'
        );
        $data4 = array(        //不符合规则的数组:键名不一致
                array('id'=>1,'name'=>'aa','age'=>33,),
                array('id'=>3,'name'=>'bb','age'=>11,'ch'=>'才'),
                array('id'=>2,'name'=>'cc','age'=>22,'ch'=>'不'),
        );

        $ms = new Makesorts($data2);
        //var_dump($ms -> getData());
        //var_dump($ms -> getKeys());
        //var_dump($ms -> setData($data2) -> makeSorts());
        //var_dump($ms -> makeSorts());
        //var_dump($ms -> makeSorts(array('id'),false,'asc'));
        //var_dump($ms -> makeSorts('id,age',true,'asc','_paixu'));
        //var_dump($ms);
        
        //$ms2 = new Makesorts($data4);
        //var_dump($ms2 -> getError());
}


test();
测试效果如图:


本帖最近评分记录
  • 咖啡 无忧币 +20 赞赞赞! 2017-6-28 10:07



本帖最后由 七彩极 于 2017-11-13 19:40 编辑
2014年编写的成绩管理系统 介绍:
http://bbs.51cto.com/thread-1109381-1.html

现在都改用thinkphp开发了哈~!
以前我都是用函数来实现,最近才开始慢慢练习写类封装哈~!

有些写得不够完善的,或者有漏洞错误的,请大家指正哟!




本帖最后由 七彩极 于 2017-6-28 09:15 编辑
宝剑厉不厉害,要看它的主人是谁,不信来PHP版块看看~!
虽然看不懂……但是一定要支持~



‹‹ 上一贴:【源码分享】PHP 基础 在线文件管理系统 ...   |   下一贴:【教程经验】实际项目中include返回数组的调用解析 ... ››
  发新话题
快速回复主题
关于我们 | 诚聘英才 | 联系我们 | 网站大事 | 友情链接 |意见反馈 | 网站地图
Copyright©2005-2017 51CTO.COM
本论坛言论纯属发布者个人意见,不代表51CTO网站立场!如有疑义,请与管理员联系:bbs@51cto.com