详解PHP中数组函数的巧用

顾言
顾言
发布时间:2026-10-15| 6人浏览过
原创

PHP的内置数组函数基于C语言编写,执行效率远高于手动遍历。本文结合实际开发场景,详细解析如何利用array_intersect_key提取指定键名、利用array_diff_key排除字段,并深入探讨array_flip实现高效去重和重置索引的技巧。同时涵盖使用array_filter智能过滤空值、利用array_product验证全真布尔数组,以及如何组合使用array_keys、array_slice与array_search截取特定区间数组。最后分享使用array_count_values统计最高频值的通用算法。

前言

PHP的数组是一种非常强大的数据类型。PHP提供了一系列高效的内置数组函数来处理日常开发中的数据操作。相比手写循环,善用这些由C语言实现的底层函数,能显著提升代码的执行速度和运行性能。以下是在各类常见场景中灵活运用这些内置函数的方法。

取指定键名

在处理关联数组时,通常需要从中提取特定的几个键名对应的数据。例如从包含'id'、'name'和'password'的数组中仅保留id和name字段。

下面对比两种实现方式:

<?php
$raw = ['id' => 1, 'name' => 'zane', 'password' => '123456'];
// 自定义逻辑:遍历原数组并根据目标键进行筛选
function onlyKeys($raw, $keys) {
    $new = [];
    foreach ($raw as $key => $val) {
        if (in_array($key, $keys)) {
            $new[$key] = $val;
        }
    }
    return $new;
}
// 使用内置函数实现
function newOnlyKeys($array, $keys) {
    // array_flip将传入的键名字符串数组转换为值-键形式,以便作为键名进行比较
    // array_intersect_key根据第一个数组的键名计算交集
    return array_intersect_key($array, array_flip($keys));
}
var_dump(onlyKeys($raw, ['id', 'name']));
var_dump(newOnlyKeys($raw, ['id', 'name']));
// 两者输出均为: ['id' => 1, 'name' => 'zane']
?>

内置方案核心原理在于:array_flip函数会交换数组的键名和键值,将目标键名字符串数组转为哈希映射;array_intersect_key函数则根据键名的相等性计算数组交集。这一组合可以非常简洁地完成字段提取任务。

移除指定键名

既然可以通过交集取出指定字段,同理,也可以轻松移除不需要的字段,实现“黑盒”式的字段排除。

<?php
$raw = ['id' => 1, 'name' => 'zane', 'password' => '123456'];
function removeKeys($array, $keys) {
    // 与上方类似,但使用差集函数剔除指定键名
    return array_diff_key($array, array_flip($keys));
}
// 移除 id 和 password 键
var_dump(removeKeys($raw, ['id', 'password']));
// 结果: ['name' => 'zane']
?>

array_diff_key的作用是使用键名比较计算数组的差集。它与array_intersect_key互为反向操作,同样配合array_flip即可快速清理冗余数据。

数组去重

对于需要去除重复元素的场景,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]
? >

高性能替代方案:
在某些对性能敏感的场景下,可以利用array_flip连续两次调用来实现去重。原理是PHP数组的键名具有唯一性,当第一次翻转(flip)后,原数组的值变成了键,原本的重复值因键名冲突被覆盖而自动去重;第二次再翻转回来,即可恢复为原数组结构。

<?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]
?>

差异注意:
上述方法与array_unique的结果存在细微差别。array_unique保留的是原数组中**最先出现**的键名,而array_flip(array_flip())由于键值覆盖的原理,最终保留的是原数组中**最后出现**的键名。
此外,这种双重翻转法要求数组的值必须是能够作为合法键名的类型(即String或Integer),否则会被忽略。如果需要重新整理索引,可配合array_values使用。

重置索引

当数组的数字键名不连续(如[0 => 233, 99 => 666])时,若需将其重置为标准的0到N连续索引,可使用array_values函数。

<?php
$input = [0 => 233, 99 => 666];
var_dump(array_values($input));
// 结果: [0 => 233, 1 => 66]
?>

array_values不仅会重置数字索引,还会彻底删除所有的字符串键名。如果在保留字符串键名的同时只重置数字索引,可以使用array_slice。

<?php
$input = ['hello' => 'world', 0 => 233, 99 => 666];
// array_slice 默认会对切片后的新数组重置数字索引
var_dump(array_slice($input, 0));
// 结果保留了字符串键名,并将数字索引重置为连续状态
?>

清除空值

在清洗数据时,经常需要剔除数组中的所有空值元素(包括 null、false、0、0.0、空数组 '' 等)。此时可以使用array_filter函数。

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

如果不给array_filter传回调函数,它会默认移除所有等价于布尔值 false 的元素。值得注意的是,像字符串 '0' 或者整型 0 等在某些业务逻辑下可能具有实际意义的值也会被一同移除。如果业务规则认为这些值不应被视为“空”,则需要自行编写callback回调函数来定义过滤条件。

确认数组成员全部为真

如果想验证一个关联数组中的多个权限开关是否全部开启(值全为true),除了循环判断,还可以采用巧妙的数学方法:使用array_product函数计算所有值的乘积。

<?php
$power = ['read' => true, 'write' => true, 'execute' => true];
// 计算乘积,将所有值隐式转换为数值:true变为1,false变为0
// 只有当所有元素均为真(true/1)时,累乘结果才为1(真),否则必为0(假)
var_dump((bool)array_product($power));
// 结果: true
?>
<?php
$power = ['read' => true, 'write' => true, 'execute' => false];
var_dump((bool)array_product($power));
// 结果: false
?>

该方法的本质是利用乘法分配律的逻辑特性:只要有一个值为 false(转为 0),总乘积即为 0。在使用前请务必确认数组内的值转为数值型后的表现符合预期。例如字符串 'true' 或某些字母字符在转为数值时可能被视作0。

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

若要截取关联数组中某个键名之前的片段,由于array_slice依赖整数偏移量(位置索引),我们可以通过组合三个函数来实现:array_keys获取键的位置索引,array_search查找目标键名的偏移量,array_slice进行切片。

<?php
$data = ['first' => 1, 'second' => 2, 'third' => 3];
function beforeKey($array, $key) {
    $keys = array_keys($array);
    $offset = array_search($key, $keys);
    // 返回偏移量之前的部分
    return array_slice($array, 0, $offset);
}
var_dump(beforeKey($data, 'first'));   // 结果为空数组 []
var_dump(beforeKey($data, 'second'));  // 结果: ['first' => 1]
var_dump(beforeKey($data, 'third'));   // 结果: ['first' => 1, 'second' => 2]
?>

同理,获取指定键名之后的数组也非常简单,只需调整array_slice的参数即可:

<?php
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]
?>

数组中重复次数最多的值

此场景常用于统计分析,例如找出一组数据中出现频率最高的元素。关键工具是array_count_values配合排序函数。

<?php
$data = [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8];
// 统计每个值出现的次数,生成形如 ['11' => 4, '6' => 2...] 的数组
$cv = array_count_values($data);
// arsort 按照值的大小降序排列,并保持键值关联
arsort($cv);
// key() 获取当前指向单元(也就是最大值所在的单元)的键名
$max = key($cv);
var_dump($max);
// 结果: 11
?>

流程清晰明了:array_count_values先将原始数组转化为计数统计表;接着调用arsort按频次从高到低排序;最后使用key()定位到数组的第一个键,该键即为原数组中最频繁出现的元素。

以上就是详解PHP中数组函数的巧用的详细内容,更多关于PHP数组函数的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。