问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

在数组中搜索给定的值,如果成功则返回首个相应的键名?

发布网友 发布时间:2022-04-24 04:50

我来回答

2个回答

热心网友 时间:2022-04-06 09:10

array_search
(PHP 4 >= 4.0.5, PHP 5, PHP 7)
array_search — 在数组中搜索给定的值,如果成功则返回首个相应的键名
说明
array_search ( mixed $needle , array $haystack [, bool $strict = false ] ) : mixed
大海捞针,在大海(haystack)中搜索针( needle 参数)。
参数
needle
搜索的值。
注意:
如果 needle 是字符串,则比较以区分大小写的方式进行。
haystack
这个数组。
strict
如果可选的第三个参数 strict 为 true,则 array_search() 将在 haystack 中检查完全相同的元素。 这意味着同样严格比较 haystack 里 needle 的 类型,并且对象需是同一个实例。
返回值
如果找到了 needle 则返回它的键,否则返回 false。
如果 needle 在 haystack 中出现不止一次,则返回第一个匹配的键。要返回所有匹配值的键,应该用 array_keys() 加上可选参数 search_value 来代替。
警告
此函数可能返回布尔值 false,但也可能返回等同于 false 的非布尔值。请阅读 布尔类型章节以获取更多信息。应使用 === 运算符来测试此函数的返回值。
更新日志
版本说明
5.3.0As with all internal PHP functions as of 5.3.0, array_search() returns null if invalid parameters are passed to it.

热心网友 时间:2022-04-06 10:28

巧用 PHP 数组函数

程序猿的生活1
09-10
0x00 前言

PHP 的数组是一种很强大的数据类型,与此同时 PHP 内置了一系列与数组相关的函数可以很轻易的实现日常开发的功能。但是我发现好像很多小伙伴都忽略了内置函数的作用(比如我自己就编写过一些有关数组操作的代码然后发现PHP自带了/(ㄒoㄒ)/~~),善用 PHP 内置函数能极大的提高开发效率和运行效率(内置函数都是用 C 写的效率比用 PHP 写的高很多),所以本文便总结了一些在常见场景中利用 PHP 内置函数的实现方法。此外如果想更深入的学习有关 PHP 数组函数最好还是去查 PHP 手册!点我看官方数组函数手册

10年架构师领你架构-成长之路-

0x01 取指定键名

对于某些关联数组,有时候我们只想取指定键名的那部分,比如数组为 ['id' => 1, 'name' => 'zane', 'password' => '123456'] 此时若只想取包含 id 和 name 的部分该怎么实现呢?下面直接贴代码。

<?php$raw = ['id' => 1, 'name' => 'zane', 'password' => '123456'];// 自己用 PHP 实现function onlyKeys($raw, $keys) { $new = []; foreach ($raw as $key => $val) { if (in_array($key, $keys)) { $new[$key] = $val; } } return $new;}// 用 PHP 内置函数实现function newOnlyKeys($array, $keys) { return array_intersect_key($array, array_flip($keys));}var_mp(onlyKeys($raw, ['id', 'name']));// 结果 ['id' => 1, 'name' => 'zane']var_mp(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_flip array_intersect_key

0x02 移除指定键名

有了上一个例子做铺垫,这个就简单讲讲啦,道理是大同小异滴。

<?php$raw = ['id' => 1, 'name' => 'zane', 'password' => '123456'];// 用 PHP 内置函数实现function removeKeys($array, $keys) { return array_diff_key($array, array_flip($keys));}// 移除 id 键var_mp(removeKeys($raw, ['id', 'password']));// 结果 ['name' => 'zane']
和上一个例子相比本例只是将 array_intersect_key 函数改为 array_diff_key,嗯……相信大家能猜出来这个函数的功能「使用键名比较计算数组的差集」,刚好和 array_intersect_key 的功能相反而已。官方手册:array_diff_key 0x03 数组去重

这个相信大家都有这个需求,当然 PHP 也内置了array_unique函数供给大家使用,如下例:

<?php$input = ['you are' => 666, 'i am' => 233, 'he is' => 233, 'she is' => 666];$result = array_unique($input);var_mp($result);// 结果 ['you are' => 666, 'i am' => 233]
嘿,用这个函数就能解决大部分问题了,但是有时候你可能会觉得它不够快,原因如下: array_unique() 先将值作为字符串排序,然后对每个值只保留第一个遇到的键名,接着忽略所有后面的键名。 因为这个函数会先将数组进行排序,所以速度可能在某些场景达不到预期的要求。 现在我们可以祭出我们的黑科技 array_flip 函数,众所周知 PHP 里数组的键名是唯一的,所以在键名和值对调后重复的值便被忽略了。试想一下我们连续调用两次 array_flip 函数是不是就相当于实现了 array_unique 函数的功能呢?示例代码如下:

<?php$input = ['you are' => 666, 'i am' => 233, 'he is' => 233, 'she is' => 666];$result = array_flip(array_flip($input));var_mp($result);// 结果 ['she is' => 666, 'he is' => 233]
嗯哼?!结果和 array_unique 的不一样!为什么,我们可以从 PHP 官方手册得到答案: 如果同一个值出现多次,则最后一个键名将作为它的值,其它键会被丢弃。 总的来说就是 array_unique 保留第一个出现的键名,array_flip 保留最后一个出现的键名。

注意:使用 array_flip 作为数组去重时数组的值必须能够作为键名(即为 string 类型或 integer 类型),否则这个值将被忽略。 此外,若不需要保留键名我们可以直接这样使用 array_values(array_flip($input))。 0x04 重置索引 当我们想要对一个索引并不连续的数组进行重置时,比如数组:[0 => 233, 99 => 666],对于这种数组我们只需要调用 array_values 函数即可实现。如下例:

<?php$input = [0 => 233, 99 => 666];var_mp(array_values($input));// 结果 [0 => 233, 1 => 66]
需要注意的是array_values函数并不止重置数字索引还会将字符串键名也同样删除并重置。那如何在保留字符串键名的同时重置数字索引呢?答案就是array_slice函数,代码示例如下:

<?php$input = ['hello' => 'world', 0 => 233, 99 => 666];var_mp(array_slice($input, 0));// 结果 ['hello' => 'world', 0 => 233, 1 => 66]
array_slice函数的功能是取出数组的中的一段,但它默认会重新排序并重置数组的数字索引,所以可以利用它重置数组中的数字索引。

0x05 清除空值

嘿,有时候我们想清除某个数组中的空值比如:null、false、0、0.0、[]空数组、''空字符串、'0'字符串0 ,这时 array_filter 函数便能帮上大忙。代码如下:

<?php$input = ['foo', false, -1, null, '', []];var_mp(array_filter($input));// 结果 [0 => 'foo', 2 => -1]
为什么会出现这样的结果捏?array_filter 的作用其实是「用回调函数过滤数组中的单元」,它的第二个参数其实是个回调函数,向数组的每个成员都执行这个回调函数,若回调函数的返回值为 true 便保留这个成员,为 false 则忽略。这个函数还有一个特性就是: 如果没有提供 callback 函数, 将删除 array 中所有等值为 FALSE 的条目。 等值为 false 就是转换为 bool 类型后值为 false 的意思,详细看文档:转换为布尔类型。

注意:如果不填写 callback 函数,0、0.0、'0'字符串0 这些可能有意义的值会被删除。所以如果清除的规则有所不同还需要自行编写 callback 函数。

0x06 确认数组成员全部为真 有时候我们希望确认数组中的的值全部为 true,比如:['read' => true, 'write' => true, 'execute' => true],这时我们需要用一个循环判定吗?NO,NO,NO……只需要用 array_proct 函数便可以实现了。代码如下:

<?php$power = ['read' => true, 'write' => true, 'execute' => true];var_mp((bool)array_proct($power));// 结果 true$power = ['read' => true, 'write' => true, 'execute' => false];var_mp((bool)array_proct($power));// 结果 false
为什么能实现这个功能呢? array_proct 函数本来的功能是「计算数组中所有值的乘积」,在累乘数组中所有成员的时候会将成员的值转为数值类型。当传递的参数为一个 bool 成员所组成的数组时,众所周知 true 会被转为 1,false 会被转为 0。然后只要数组中出现一个 false 累乘的结果自然会变成 0,然后我们再将结果转为 bool 类型不就是 false 了嘛!

注意:使用 array_proct 函数将在计算过程中将数组成员转为数值类型进行计算,所以请确保你了解数组成员转为数值类型后的值,否则会产生意料之外的结果。比如:

<?php$power = ['read' => true, 'write' => true, 'execute' => 'true'];var_mp((bool)array_proct($power));// 结果 false
上例是因为'true'在计算过程中被转为 0。要想详细了解请点击这里。

0x07 获取指定键名之前 / 之后的数组

如果我们只想要关联数组中指定键名值之前的部分该怎么办呢?又用一个循环?当然不用我们可以通过 array_keys、array_search 和 array_slice 组合使用便能够实现!下面贴代码:

<?php$data = ['first' => 1, 'second' => 2, 'third' => 3];function beforeKey($array, $key) { $keys = array_keys($array); // $keys = [0 => 'first', 1 => 'second', 2 => 'third'] $len = array_search($key, $keys); return array_slice($array, 0, $len);}var_mp(beforeKey($data, 'first'));// 结果 []var_mp(beforeKey($data, 'second'));// 结果 ['first' => 1]var_mp(beforeKey($data, 'third'));// 结果 ['first' => 1, 'second' => 2]
思路解析,要实现这样的功能大部分同学都应该能想到 array_slice 函数,但这个函数取出部分数组是根据偏移量(可以理解为键名在数组中的顺序,从 0 开始)而不是根据键名的,而关联数组的键名却是是字符串或者是不按顺序的数字,此时要解决的问题便是「如何取到键名对应的偏移量?」,这是 array_keys 函数便帮了我们大忙,它的功能是「返回数组中部分的或所有的键名」默认返回全部键名,此外返回的键名数组是以数字索引的,也就是说返回的键名数组的索引就是偏移量!例子中的原数组变为: [0 => 'first', 1 => 'second', 2 => 'third'] 。然后我们通过 array_search 便可以获得指定键名的偏移量了,因为这个函数的功能是「在数组中搜索给定的值,如果成功则返回首个相应的键名」。有了偏移量我们直接调用 array_slice 函数便可以实现目的了。 上面的例子懂了,那获取指定键名之后的数组也就轻而易举了,略微修改 array_slice 即可。直接贴代码:

<?php$data = ['first' => 1, 'second' => 2, 'third' => 3];function afterKey($array, $key) { $keys = array_keys($array); $offset = array_search($key, $keys); return array_slice($array, $offset + 1);}var_mp(afterKey($data, 'first'));// 结果 ['second' => 2, 'third' => 3]var_mp(afterKey($data, 'second'));// 结果 ['third' => 3]var_mp(afterKey($data, 'third'));// 结果 []
那如何获取指定值之前或之后的数组呢?嘿,记得 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 函数。实例代码如下:

<?php$data = [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8];$cv = array_count_values($data);// $cv = [6 => 2, 11 => 4, 2 => 2, 4 => 3, 7 => 1, 8 => 1]arsort($cv);$max = key($cv);var_mp($max);// 结果 11
array_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_mp($max);// 结果 11
欢迎大家给我提 issue 和 pr,另外如果你喜欢这个项目希望动动小手点个 star :-D 项目地址:github.com/zanemmm/uti…

0x0A 结语

其实还有很多实用的函数没有介绍,但是限于文章篇幅就讲到这里了吧。本文出现的很多例子都并非本人原创的,多数出于 PHP 官方手册(每个函数功能下面的评论里都有很多大神提出一些厉害的用法,部分示例就是出自评论)。在下只是拾人牙慧,将其总结了一下。另外文章中若出现错误,希望大家能够指出,若有疑问可以互相讨论:-D。

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以点击查看详细资料!!

喜欢我的文章就关注我吧,持续更新中.....

搜索
初学编程100个代码
普通人自学编程有用吗
自学编程该如何入手
最简单的php函数
从零开始学编程怎么学
java自学一般要学多久
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
初中英语语法讲解:名词所有格 关于名词所有格一问 暗区突围画面怎么设置最好-暗区突围画面设置推荐 暗区突围打开的箱子怎么关上 保险箱关闭攻略 暗区突围 暗区突围画面设置怎么弄最佳? 暗区突围 暗区突围光影怎么调? 暗区突围 暗区突围中间白点怎么设置? 暗区突围灵敏度怎么调最稳 暗区突围灵敏度最佳设置方法 我的WIN7 64位系统无法安装打印机HP1136,请支持啊,急。驱动下载也没用... win7电脑连接不上惠普打印机Win7系统安装不了惠普HP1007打印机 kafka mysql hbase mongodb怎样组合 kafka怎么样接收数据保存到MYSQL数据库 大客户管理对企业而言具有什么意义 怎么做大客户维护? 大客户营销的步骤 大客户管理的6大步骤是什么 简单叙述大客户管理的原则 如何进行外贸大客户管理 大客户管理的工作规范 [企业管理100问]如何管理大客户,有哪些技巧? 有知道康巴赫不粘锅两百多元和肆百多元的有多大区别? 大客户管理如何做到一户一策 c语言中为什么栈的初始化时候栈顶指针要指向-1? 大客户管理的介绍 工商银行电话如何做好大客户管理 康巴赫蜂窝不粘锅好用不?用过的来说说。 男生宽脚适合穿什么鞋 康巴赫炒锅怎么样?用过的来说说。 大客户管理的解决方案 大客户管理最有效的方法是什么?怎样提高大客的忠诚度? 如何监控Mysql里插入一条数据 kafka生产者就生产这条数据 猕猴桃有一点点坏了还能吃吗 猕猴桃烂了一点能吃吗 猕猴桃有点烂的能吃吗 猕猴桃烂了一块还能吃吗 猕猴桃坏了能吃吗有毒吗 猕猴桃一半硬一半烂还能吃吗? 猕猴桃局部烂还能吃吗 猕猴桃有一点坏了的,好地方还能吃吗? 猕猴桃烂了真的能吃吗 猕猴桃有斑点还能吃吗 猕猴桃坏了吃了会怎么样 猕猴桃一半硬一半烂还能吃吗 猕猴桃坏了一半还能吃吗 猕猴桃软的外面是好的,里面感觉有点坏啦能吃吗 男孩性器官几岁开始发育? 小男孩的生殖器什么时候开始发育? 男生一般在什么时候开始发育 天津汽车摇号申请网是什么? 男性生殖器官的发育期在什么时候