当前位置: 首页 > 后端技术 > PHP

使用PHP数组函数

时间:2023-03-30 01:45:10 PHP

0x00前言PHP数组是一种非常强大的数据类型。同时,PHP内置了一系列与数组相关的函数,可以轻松实现日常开发的功能。但是我发现很多朋友似乎忽略了内置函数的作用(比如我写了一些数组操作相关的代码,发现PHP自带/(ㄒoㄒ)/~~),好好利用PHP内置函数可以大大提高开发效率和运行效率(内置函数是用C写的,比PHP写的效率高很多),所以本文总结了一些使用PHP内置函数的实现方法在常见的场景中。另外,如果想深入了解PHP数组函数,最好查看PHP手册!点我看官方数组函数手册0x01获取指定键名对于一些关联数组,有时候我们只想获取指定键名的部分,比如数组是['id'=>1,'name'=>'zane','password'=>'123456']这个时候如果只想获取id和name这部分,怎么实现呢?下面直接贴代码。1,'name'=>'zane','password'=>'123456'];//用PHP实现函数onlyKeys($raw,$keys){$新=[];foreach($rawas$key=>$val){if(in_array($key,$keys)){$new[$key]=$val;}}return$new;}//使用PHP内置函数实现functionnewOnlyKeys($array,$keys){returnarray_intersect_key($array,array_flip($keys));}var_dump(onlyKeys($raw,['id','name']));//结果['id'=>1,'name'=>'zane']var_dump(newOnlyKeys($raw,['id','name']));//结果['id'=>1,'name'=>'zane']显然简单了很多!但是array_intersect_key和array_flip到底是什么鬼?下面简单介绍一下这两个函数的作用。第一个是array_flip函数。该函数的作用是“将数组的键值对调”,即键名变成值,值变成键名。我们传递的$keys参数通过这个函数从[0=>'id',1=>'name']变成了['id'=>0,'name'=>1]。这样做的目的是为array_intersect_key函数服务。array_intersect_key函数的作用是“使用键名比较计算数组的交集”,即返回第一个参数数组中与其他参数数组相同键名的值。这样就实现了取指定键名的功能~(≧▽≦)/~!当然,如果想详细了解这两个函数的作用,还是需要查看PHP官方手册:array_fliparray_intersect_key0x02去掉指定键名。有了前面的例子做铺垫,这里简单说明一下。原因类似。1,'name'=>'zane','password'=>'123456'];//实现函数removeKeys($array,$keys){returnarray_diff_key($array,array_flip($keys));}//移除idkeyvar_dump(removeKeys($raw,['id','password']));//结果['name'=>'zane']与前面的例子,这个例子只是把array_intersect_key函数改成了array_diff_key,嗯……相信你也能猜到这个函数的作用“computethedifferenceofarraysusingkeynamecomparison”,正好和array_intersect_key的函数相反.官方手册:array_diff_key0x03数组去重相信大家都有这个需求。当然PHP也内置了array_unique函数供大家使用。下面的例子:666,'我是'=>233,'他是'=>233,'她是'=>666];$result=array_unique($input);var_dump($result);//Result['youare'=>666,'iam'=>233]嘿,这个函数会解决大部分问题,但有时你可能会觉得它不够快原因如下:array_unique()首先将值作为字符串排序,然后对于每个值只保留第一个遇到的键名,然后忽略后面所有的键名。因为这个函数是先对数组进行排序,所以在某些场景下速度可能达不到预期的要求。现在可以使用我们的黑科技array_flip函数,我们都知道PHP中数组的键名是唯一的,所以键名和值交换后,重复的值会被忽略。试想一下,如果我们连续两次调用array_flip函数,是不是就相当于实现了array_unique函数的功能呢?示例代码如下:666,'我是'=>233,'他是'=>233,'她是'=>666];$result=array_flip(array_flip($input));var_dump($result);//结果['sheis'=>666,'heis'=>233]嗯?!结果和array_unique的不一样!为什么呢,我们可以从PHP官方手册中得到答案:如果同一个值出现多次,最后一个键名会作为它的值,其他的键会被丢弃。一般来说,array_unique保留第一次出现的键名,array_flip保留最后一次出现的键名。注意:使用array_flip作为数组去重时,数组的值必须能够作为键名(即字符串类型或整数类型),否则该值将被忽略。另外,如果我们不需要保留键名,我们可以直接这样使用array_values(array_flip($input))。0x04重置索引当我们要重置一个索引不连续的数组时,比如数组:[0=>233,99=>666],我们只需要为这种数组调用array_values函数即可。下面的例子:233,99=>666];var_dump(array_values($input));//result[0=>233,1=>66]需要注意array_values函数不仅会重置numericindex,还会重置stringkey删除并重置。那么如何在保留字符串键名的同时重置数字索引呢?答案是array_slice函数,代码示例如下:'world',0=>233,99=>666];var_dump(array_slice($input,0));//result['hello'=>'world',0=>233,1=>66]array_slice函数的作用是取出数组的一段,但是会重新排序并重新设置数值索引默认情况下是数组的索引,因此您可以使用它重置数组中的数字索引。0x05清除空值哎,有时候我们要清除数组中的空值如:null,false,0,0.0,[]空数组,''空字符串,'0'字符串0,然后array_filter函数会有很大的帮助。代码如下:'foo',2=>-1]为什么会有这样的结果捏?array_filter的作用其实就是“用回调函数过滤数组中的元素”。它的第二个参数其实是一个回调函数,为数组的每个成员执行。如果回调函数的返回值为true,this将被保留成员,false则忽略。该函数的另一个特点是,如果不提供回调函数,则删除数组中所有等效值为FALSE的条目。等效值为false,即转bool类型后为false。详见文档:转Boolean类型。注意:如果不填写回调函数,可能有意义的值如0、0.0、'0'字符串0将被删除。所以如果清算规则不同,需要自己写回调函数。0x06确认所有数组成员都为真有时候我们想确认数组中所有的值都为真,比如:['read'=>true,'write'=>true,'execute'=>true],那我们需要用A循环判断吗?NO,NO,NO...就用array_product函数来实现吧。代码如下:true,'write'=>true,'execute'=>true];var_dump((bool)array_product($power));//结果true$power=['read'=>true,'write'=>true,'execute'=>false];var_dump((bool)array_product($power));//为什么false的结果可以实现这个功能?array_product函数的原始功能是“计算数组中所有值的乘积”。当数组中的所有成员相乘时,成员的值将被转换为数值类型。当传递的参数是bool成员数组时,众所周知,true会转为1,false会转为0。那么数组中只要有false的乘法结果,自然就变成0,然后我们把结果转成bool类型,就会为false!注意:使用array_product函数会在计算过程中将数组成员转为数值类型进行计算,所以请务必理解数组成员转为数值类型后的值,否则会出现意想不到的结果。例如:true,'write'=>true,'execute'=>'true'];var_dump((bool)array_product($power));//结果是false示例,因为'true'在计算过程中被转换为0。要了解更多信息,请点击此处。0x07获取指定键名之前/之后的数组如果我们只想要关联数组中指定键名的值之前的部分怎么办?另一个循环?当然,我们可以通过组合array_keys、array_search和array_slice来实现!粘贴下面的代码:1,'second'=>2,'third'=>3];functionbeforeKey($array,$key){$keys=array_keys($大批);//$keys=[0=>'first',1=>'second',2=>'third']$len=array_search($key,$keys);returnarray_slice($array,0,$len);}var_dump(beforeKey($data,'first'));//result[]var_dump(beforeKey($data,'second'));//result['first'=>1]var_dump(beforeKey($data,'third'));//Result['first'=>1,'second'=>2]思路分析,实现这样的功能,大部分同学应该可以想到array_slice这个函数,但是这个函数取出来的部分数组是根据偏移量(可以理解为键名在数组中的顺序,从0开始)而不是键名,而键名关联数组的是无序的字符串或数字。这时候要解决的问题就是“如何获取键名对应的偏移量?”这就是对我们帮助很大的array_keys函数。它的作用是“返回数组中的部分或全部键名”,默认返回所有键名。另外,返回的键名数组是用数字索引的,也就是说返回的键名数组的索引就是偏移量!示例中的原始数组变为:[0=>'first',1=>'second',2=>'third']。那么我们就可以通过array_search得到指定键名的偏移量,因为这个函数的作用是“在数组中搜索给定的值,如果成功则返回第一个对应的键名”。有了偏移量,我们就可以直接调用array_slice函数来达到目的。如果理解了上面的例子,就很容易得到指定键名后面的数组,只需要稍微修改一下array_slice即可。直接贴代码:1,'second'=>2,'third'=>3];functionafterKey($array,$key){$keys=array_keys($大批);$offset=array_search($key,$keys);返回array_slice($array,$offset+1);}var_dump(afterKey($data,'first'));//结果['second'=>2,'third'=>3]var_dump(afterKey($data,'second'));//结果['third'=>3]var_dump(afterKey($data,'third'));//Result[]那么如何获取指定值前后的数组呢?嘿嘿,记住array_search的作用,其实我们只需要像这样调用beforeKey($data,array_search($value,$data))就可以实现了!0x08数组中重复次数最多的值敲黑板,画出关键点!据说这是一道面试题。假设有这样一个数组[6,11,11,2,4,4,11,6,7,4,2,11,8],如何获取数组中重复次数最多的值呢?关键在于array_count_values这个函数。示例代码如下:2,11=>4,2=>2,4=>3,7=>1,8=>1]arsort($cv);$max=key($cv);var_dump($max);//Result11array_count_values函数的作用是“统计数组中所有的值”,即使用中的值原始数组作为返回数组的键,值出现的次数作为返回数组的值。这样我们就可以使用arsort函数将出现的次数降序排列,保持索引关联。最后使用key获取当前单元的键名(当前单元默认为数组的第一个成员),此时的键名为原数组中重复次数最多的值。0x09广告时间PHP虽然提供了很多数组相关的函数,但是使用起来还是不太方便,都是函数调用,没有面向对象实现,所以最近在写一个开源工具项目zane/utils封装了一些常用的方法并支持链式调用。Ary类只用一行实现“获取数组中重复次数最多的值”,如下:$data=[6,11,11,2,4,4,11,6,7,4,2,11,8];$max=Ary::new($data)->countValues()->maxKey();var_dump($max);//结果11欢迎大家给我issue和pr,如果你喜欢这个项目,希望大家能给我一个star:-D项目地址:https://github.com/zanemm/utils0x0A结论其实还是有很多有用的功能的。简介,但限于文章篇幅,就到此为止吧。本文中的很多例子都不是我原创的,大部分来自PHP官方手册(在每个函数下面的注释中,有很多大神提出了一些强大的用法,还有一些例子来自注释).以下只是摘取大家的牙齿智慧总结一下。另外,如果文中有错误,希望大家指出,有问题可以互相讨论:-D。我的博客原创