PHP 数组函数妙用
巧妙利用php数组函数,解决二维数组查找问题
问题描述
最近在开发中遇到一个需求,突发奇想用php数组函数解决,在此记录一下。
问题简述:假设从数据表中取出所有同学成绩,需要按照如下规则进行查找数据:
1、找出所有同学中语文成绩最好的同学;
2、在1的基础上接着找到数学成绩最高的同学;
3、在2的基础上接着找到英语成绩最高的同学;
解决思路
刚遇到这个需求,第一反应就是不断循环数组进行查找过滤,思路没啥问题就是写出来代码过于丑陋,php毕竟是世界上最好的
语言,不可能没有其他处理办法,终于在一番头脑风暴之后找到下面思路:
* 利用array_column函数取得所有同学语文成绩;
* 接着用max函数找到语文最高分;
* 最后用array_filter过滤出语文最高分的同学们;
* 循环前三步,即可解决上述问题;
直接上代码
$grades = [
['name'=>'姓名一','语文'=>85,'数学'=>99,'英语'=>77],
['name'=>'姓名二','语文'=>85,'数学'=>99,'英语'=>77],
['name'=>'姓名三','语文'=>99,'数学'=>67,'英语'=>50],
['name'=>'姓名四','语文'=>99,'数学'=>67,'英语'=>90],
['name'=>'姓名五','语文'=>99,'数学'=>67,'英语'=>90],
['name'=>'姓名六','语文'=>99,'数学'=>55,'英语'=>77],
['name'=>'姓名七','语文'=>99,'数学'=>55,'英语'=>77],
['name'=>'姓名八','语文'=>86,'数学'=>88,'英语'=>90],
['name'=>'姓名九','语文'=>86,'数学'=>88,'英语'=>90],
['name'=>'姓名十','语文'=>86,'数学'=>88,'英语'=>90],
['name'=>'姓名1','语文'=>86,'数学'=>76,'英语'=>77],
['name'=>'姓名2','语文'=>86,'数学'=>76,'英语'=>60],
['name'=>'姓名3','语文'=>77,'数学'=>76,'英语'=>60],
];
// 找到语文最高分
$yuwenMax = max(array_column($grades,'语文'));
$grades = array_filter($grades,function($value) use ($yuwenMax) {
return $value['语文'] == $yuwenMax;
});
// 找到数学最高分
$shuxueMax = max(array_column($grades,'数学'));
$grades = array_filter($grades,function($value) use ($shuxueMax) {
return $value['数学'] == $shuxueMax;
});
// 找到英语最高分
$yingyuMax = max(array_column($grades,'英语'));
$grades = array_filter($grades,function($value) use ($yingyuMax) {
return $value['英语'] == $yingyuMax;
});
进一步精简代码
上述代码中,在找语文、数学、英语最高分的时候,代码基本相同,很容易想到可以用foreach循环处理,使上边的代码进一步简化。
代码如下
$columns = ['语文','数学','英语'];
foreach ($columns as $column) {
$max = max(array_column($grades,$column));
$grades = array_filter($grades,function($value) use ($max,$column) {
return $value[$column] == $max;
});
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
关于 LearnKu
laravel collect 你懂的
@dope2008 正解
数组排序多个字段啊
@安小游 用array_multisort确实可以实现排序,但是需求是要找出来对应同学。
只剩下一条数据的时候就可以返回出来了吧,不用继续查找下去了,比如「找出所有同学中语文成绩最好的同学」时就已经只剩下一条数据了的话就不必继续查找了
@xinhuo 恩,正解
这两种方式也是可以的 不过,使用多个 sort 排序的话,是从后面的有限排序的
@小龙 这个返回的$max_all和原生的不一样
@lovecn 不会吧?我试了试一样的。$sort_all->first() 得到的是第一名 然后找其他有没有和第一名 一样值的
@lovecn 是不是指数组下标的问题,如果是的话,collect有一个values方法可以重置数组下标
遇到了一个奇怪的现象,还是作者的那组数据
var_dump()得到的数正确的结果,可是,如果直接在控制器中 return 得到的却是原数据。很是困惑@小龙 敢问,找到原因了么