0x00 はじめに
PHP の配列は非常に強力なデータ型であると同時に、日々の開発を簡単に実装できる一連の配列関連関数が組み込まれています。関数。しかし、多くの友人は組み込み関数の役割を無視しているようです(たとえば、配列演算に関連するコードをいくつか書いたのに、PHP が付属していることに気づきました~~。PHP の組み込み関数を上手に活用する)開発効率と運用効率が大幅に向上するため、この記事では、一般的なシナリオで PHP 組み込み関数を使用する実装方法をいくつかまとめます。 、PHP 配列関数についてさらに詳しく知りたい場合は、PHP マニュアルを確認することをお勧めします!
##0x01 指定されたキー名を取得関連学習の推奨事項:
PHP ビデオ チュートリアル://m.sbmmt.com/course /list/29/type/2.html
#一部の連想配列では、指定されたキー名の一部を取得したい場合があります。たとえば、配列は ['id' => 1, 'name' => 'zane', 'password' => ; '123456'] 現時点では、ID と名前のみを取得したい場合は、その部分を実装する方法を教えてください。コードを直接下に貼り付けてください。
<?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_dump(onlyKeys($raw, ['id', 'name'])); // 结果 ['id' => 1, 'name' => 'zane'] var_dump(newOnlyKeys($raw, ['id', 'name'])); // 结果 ['id' => 1, 'name' => 'zane']
0x02 指定されたキー名を削除します
前の例で ステージを設定するには、次のようにします。これについて簡単に説明します。原理は似ています。
<?php $raw = ['id' => 1, 'name' => 'zane', 'password' => '123456']; // 用 PHP 内置函数实现 function removeKeys($array, $keys) { return array_diff_key($array, array_flip($keys)); } // 移除 id 键 var_dump(removeKeys($raw, ['id', 'password'])); // 结果 ['name' => 'zane']
0x03 配列の重複排除
誰もがこのニーズを持っていると思います。もちろん、PHP には誰でも使用できる組み込みの array_unique 関数もあります。次の例に示すように:
<?php $input = ['you are' => 666, 'i am' => 233, 'he is' => 233, 'she is' => 666]; $result = array_unique($input); var_dump($result); // 结果 ['you are' => 666, 'i am' => 233]
<?php $input = ['you are' => 666, 'i am' => 233, 'he is' => 233, 'she is' => 666]; $result = array_flip(array_flip($input)); var_dump($result); // 结果 ['she is' => 666, 'he is' => 233]
0x04 インデックスのリセット
配列: [0 => 233, 99 => 666] など、インデックスが連続していない配列をリセットしたい場合、この種の配列の場合、array_values 関数を呼び出すだけでそれを実現できます。例として:
<?php $input = [0 => 233, 99 => 666]; var_dump(array_values($input)); // 结果 [0 => 233, 1 => 66]
<?php $input = ['hello' => 'world', 0 => 233, 99 => 666]; var_dump(array_slice($input, 0)); // 结果 ['hello' => 'world', 0 => 233, 1 => 66]
0x05 空の値をクリア
嘿,有时候我们想清除某个数组中的空值比如:null、false、0、0.0、[]空数组、''空字符串、'0'字符串0 ,这时 array_filter 函数便能帮上大忙。代码如下:
<?php $input = ['foo', false, -1, null, '', []]; var_dump(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_product 函数便可以实现了。代码如下:
<?php $power = ['read' => 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 函数将在计算过程中将数组成员转为数值类型进行计算,所以请确保你了解数组成员转为数值类型后的值,否则会产生意料之外的结果。比如:
<?php $power = ['read' => true, 'write' => true, 'execute' => 'true']; var_dump((bool)array_product($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_dump(beforeKey($data, 'first')); // 结果 [] var_dump(beforeKey($data, 'second')); // 结果 ['first' => 1] var_dump(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_dump(afterKey($data, 'first')); // 结果 ['second' => 2, 'third' => 3] var_dump(afterKey($data, 'second')); // 结果 ['third' => 3] var_dump(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_dump($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_dump($max); // 结果 11
欢迎大家给我提 issue 和 pr,另外如果你喜欢这个项目希望动动小手点个 star。
项目地址:https://github.com/zanemmm/utils
0x0A 结语
其实还有很多实用的函数没有介绍,但是限于文章篇幅就讲到这里了吧。本文出现的很多例子都并非本人原创的,多数出于 PHP 官方手册(每个函数功能下面的评论里都有很多大神提出一些厉害的用法,部分示例就是出自评论)。在下只是拾人牙慧,将其总结了一下。另外文章中若出现错误,希望大家能够指出,若有疑问可以互相讨论。
更多编程相关内容,请关注php中文网编程入门栏目!
以上がPHPの配列関数を賢く使う方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。