>백엔드 개발 >PHP 튜토리얼 >PHP 배열 함수의 작동은 무엇입니까? PHP 배열 함수 적용(코드 포함)

PHP 배열 함수의 작동은 무엇입니까? PHP 배열 함수 적용(코드 포함)

不言
不言원래의
2018-08-06 13:43:272383검색

이 기사에서 제공하는 내용은 PHP 배열 함수의 작동이 무엇인지입니다. PHP 배열 함수(코드 포함)의 적용에는 특정 참고 가치가 있습니다. 도움이 필요한 친구가 참고할 수 있기를 바랍니다.

PHP의 배열은 매우 강력한 데이터 유형입니다. 동시에 PHP에는 일상적인 개발 기능을 쉽게 구현할 수 있는 일련의 배열 관련 기능이 내장되어 있습니다. 하지만 많은 친구들이 내장 함수의 역할을 무시하는 것 같습니다(예를 들어 배열 연산과 관련된 코드를 작성했는데 PHP에 /(ㄒoㄒ)/~~가 포함되어 있다는 것을 알았습니다). PHP 내장 함수를 사용하면 개발 효율성과 운영 효율성이 크게 향상됩니다(내장 함수는 C로 작성되며 PHP로 작성된 함수보다 훨씬 효율적입니다). 따라서 이 기사에서는 PHP 내장 함수를 사용하는 몇 가지 구현 방법을 요약합니다. 일반적인 시나리오에서 기능합니다. 또한, PHP 배열 함수에 대해 더 자세히 알고 싶다면 PHP 매뉴얼을 확인하는 것이 가장 좋습니다! 공식 배열 함수 매뉴얼을 보려면 여기를 클릭하세요

지정된 키 이름 가져오기

일부 연관 배열의 경우 때로는 지정된 키 이름의 일부만 가져오고 싶을 때가 있습니다. 예를 들어 배열은 [' id' => 1 , 'name' => 'zane', 'password' => '123456'] id와 이름이 포함된 부분만 얻으려면 어떻게 해야 합니까? 바로 아래에 코드를 붙여넣으세요. ['id' => 1, 'name' => 'zane', 'password' => '123456'] 此时若只想取包含 id 和 name 的部分该怎么实现呢?下面直接贴代码。

<?php
$raw = [&#39;id&#39; => 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']

很明显简洁很多有木有!不过 array_intersect_keyarray_flip 是什么鬼?这里简单的介绍一下这两个函数的作用,首先是 array_flip 函数,这个函数的功能是「将数组的键和值对调」,也就是键名变成值,值变成键名。我们传递的 $keys 参数经过这个函数便从 [0 => 'id', 1 => 'name'] 转变为了 ['id' => 0, 'name' => 1]。这样做的目的是为了向 array_intersect_key 函数服务,array_intersect_key 函数的功能是「使用键名比较计算数组的交集」,也就是返回第一个参数数组中与其他参数数组相同键名的值。这样便实现了取指定键名的功能 ~(≧▽≦)/~啦!当然要详细了解这两个函数的功能还是要查 PHP 官方手册:array_flip array_intersect_key

移除指定键名

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

<?php
$raw = [&#39;id&#39; => 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']

和上一个例子相比本例只是将 array_intersect_key 函数改为 array_diff_key,嗯……相信大家能猜出来这个函数的功能「使用键名比较计算数组的差集」,刚好和 array_intersect_key 的功能相反而已。官方手册:array_diff_key

 数组去重

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

<?php
$input = [&#39;you are&#39; => 666, 'i am' => 233, 'he is' => 233, 'she is' => 666];
$result = array_unique($input);
var_dump($result);
// 结果 ['you are' => 666, 'i am' => 233]

嘿,用这个函数就能解决大部分问题了,但是有时候你可能会觉得它不够快,原因如下:

array_unique() 先将值作为字符串排序,然后对每个值只保留第一个遇到的键名,接着忽略所有后面的键名。

因为这个函数会先将数组进行排序,所以速度可能在某些场景达不到预期的要求。

现在我们可以祭出我们的黑科技 array_flip 函数,众所周知 PHP 里数组的键名是唯一的,所以在键名和值对调后重复的值便被忽略了。试想一下我们连续调用两次 array_flip 函数是不是就相当于实现了 array_unique 函数的功能呢?示例代码如下:

<?php
$input = [&#39;you are&#39; => 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]

嗯哼?!结果和 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_dump(array_values($input));
// 结果 [0 => 233, 1 => 66]

需要注意的是 array_values

<?php
$input = [&#39;hello&#39; => 'world', 0 => 233, 99 => 666];
var_dump(array_slice($input, 0));
// 结果 ['hello' => 'world', 0 => 233, 1 => 66]
분명히 훨씬 더 간단하고 더 유용합니다! 그런데 array_intersect_keyarray_flip가 도대체 ​​뭐죠? 이 두 함수의 기능에 대해 간략하게 소개합니다. 첫 번째는 array_flip 함수입니다. 이 함수의 기능은 "배열의 키와 값을 교환"하는 것입니다. 키 이름이 값이 되고, 값이 키 이름이 됩니다. 이 함수를 통해 전달한 $keys 매개변수는 [0 => 'id', 1 => 'name']에서 ['id; ' => 0, '이름' => 이것의 목적은 <code>array_intersect_key 함수를 제공하는 것입니다. array_intersect_key 함수의 기능은 "키 이름 비교를 사용하여 배열의 교집합을 계산하는 것"입니다. 첫 번째 매개변수 배열을 반환합니다. 다른 매개변수 배열과 동일한 키를 가진 값입니다. 이런 식으로 지정된 키 이름을 가져오는 기능이 ~(≧<?php $input = [&#39;foo&#39;, false, -1, null, &#39;&#39;, []]; var_dump(array_filter($input)); // 结果 [0 => 'foo', 2 => -1]🎜이전 예와 비교하면 이 예는 단지 array_intersect_key 함수를 array_diff_key로 변경한 것 뿐인데... 이 함수의 기능을 짐작하실 수 있으실 거라 믿습니다. "키 사용" 이름 비교 배열의 차이 집합을 계산합니다. 이는 array_intersect_key 함수와 정반대입니다. 공식 매뉴얼: array_diff_key🎜🎜🎜 배열 중복 제거🎜🎜🎜 물론, PHP에는 다음 예와 같이 모든 사람이 사용할 수 있는 array_unique 함수가 내장되어 있습니다. 🎜
<?php
$power = [&#39;read&#39; => 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_unique()🎜 먼저 값을 문자열로 정렬한 다음 처음 발견된 키 이름만 유지합니다. 각 값을 무시한 다음 모든 후속 키 이름을 무시합니다.
🎜 이 기능은 배열을 먼저 정렬하기 때문에 일부 시나리오에서는 속도가 예상 요구 사항을 충족하지 못할 수 있습니다. 🎜🎜이제 우리는 블랙 기술인 array_flip 함수를 사용할 수 있습니다. 우리 모두 알고 있듯이 PHP 배열의 키 이름은 고유하므로 키 이름과 값 뒤에 중복된 값은 무시됩니다. 교환됩니다. array_flip 함수를 연속해서 두 번 호출한다고 상상해 보세요. array_unique 함수의 기능을 구현하는 것과 동일할까요? 샘플 코드는 다음과 같습니다. 🎜
<?php
$power = [&#39;read&#39; => true, 'write' => true, 'execute' => 'true'];
var_dump((bool)array_product($power));
// 结果 false
🎜Huh? ! 결과가 array_unique와 다릅니다! 이유는 PHP 공식 매뉴얼에서 답을 얻을 수 있습니다. 🎜🎜동일한 값이 여러 번 나타나면 마지막 키 이름이 해당 값으로 사용되고 다른 키는 삭제됩니다. 🎜🎜일반적으로 array_unique는 처음 나타나는 키 이름을 유지하고 array_flip은 마지막으로 나타나는 키 이름을 유지합니다. 🎜🎜🎜참고🎜: array_flip을 배열 중복 제거로 사용하는 경우 배열의 값을 키 이름(즉, 문자열 유형 또는 정수 유형)으로 사용할 수 있어야 합니다. 그렇지 않으면 값이 무시당하다. 🎜🎜그리고 키 이름을 유지할 필요가 없다면 이렇게 array_values(array_flip($input))를 직접 사용할 수도 있습니다. 🎜🎜🎜0x04 인덱스 재설정 🎜🎜🎜 배열과 같이 인덱스가 연속적이지 않은 배열을 재설정하려는 경우: [0 => 233, 99 => 666] 배열의 경우 이를 달성하려면 array_values ​​​​함수만 호출하면 됩니다. 예: 🎜
<?php
$data = [&#39;first&#39; => 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_values 함수는 숫자 인덱스를 재설정할 뿐만 아니라 문자열 키 이름을 삭제하고 재설정한다는 점에 유의해야 합니다. 그렇다면 문자열 키 이름을 유지하면서 숫자 인덱스를 어떻게 재설정합니까? 답은 array_slice 함수입니다. 코드 예는 다음과 같습니다. 🎜
<?php
$input = [&#39;hello&#39; => 'world', 0 => 233, 99 => 666];
var_dump(array_slice($input, 0));
// 结果 ['hello' => 'world', 0 => 233, 1 => 66]

array_slice 函数的功能是取出数组的中的一段,但它默认会重新排序并重置数组的数字索引,所以可以利用它重置数组中的数字索引。

清除空值

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

<?php
$input = [&#39;foo&#39;, false, -1, null, &#39;&#39;, []];
var_dump(array_filter($input));
// 结果 [0 => 'foo', 2 => -1]

为什么会出现这样的结果捏?array_filter 的作用其实是「用回调函数过滤数组中的单元」,它的第二个参数其实是个回调函数,向数组的每个成员都执行这个回调函数,若回调函数的返回值为 true 便保留这个成员,为 false 则忽略。这个函数还有一个特性就是:

如果没有提供 callback 函数, 将删除 array 中所有等值为 FALSE 的条目。

等值为 false 就是转换为 bool 类型后值为 false 的意思,详细看文档:转换为布尔类型。

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

 确认数组成员全部为真

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

<?php
$power = [&#39;read&#39; => 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 = [&#39;read&#39; => true, 'write' => true, 'execute' => 'true'];
var_dump((bool)array_product($power));
// 结果 false

上例是因为 'true' 在计算过程中被转为 0。要想详细了解请点击这里。

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

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

<?php
$data = [&#39;first&#39; => 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 = [&#39;first&#39; => 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)) 不就实现了嘛!

数组中重复次数最多的值

敲黑板,划重点!据说这是一道面试题喔。假设有这样一个数组 [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 获得当前单元(当前单元默认为数组第一个成员)的键名,此时的键名即是原数组的值重复次数最多的值。

总结

虽然 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);
// 结果 1

相关文章推荐:

如何用PHP读取excel文件内容、获取单元格数据

php设计模式:浅谈php单例模式(附代码)

위 내용은 PHP 배열 함수의 작동은 무엇입니까? PHP 배열 함수 적용(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.