array_filter()配合ARRAY_FILTER_USE_BOTH标志可按数组键的奇偶性筛选元素,需在匿名函数中用$k%2判断键值,适用于关联和索引数组,保留原始键名;注意“索引奇偶”指键名而非遍历位置。

用 array_filter() 配合匿名函数判断索引奇偶
PHP 数组本身不提供原生的“按索引奇偶筛选”函数,但 array_filter() 支持传入键名(需用 ARRAY_FILTER_USE_BOTH 标志),这是最直接、语义最清晰的方式。
注意:默认情况下 array_filter() 只传值,不传键;漏掉标志会导致所有元素被当成“索引为 0”处理,结果全错。
- 对关联数组和索引数组都有效
- 保留原始键名,不重置索引
- 若需重置为连续数字索引,后续加
array_values()
$arr = ['a', 'b', 'c', 'd', 'e'];
$odd_index = array_filter($arr, function($v, $k) {
return $k % 2 === 1; // 奇数索引:1, 3, 5...
}, ARRAY_FILTER_USE_BOTH);
$even_index = array_filter($arr, function($v, $k) {
return $k % 2 === 0; // 偶数索引:0, 2, 4...
}, ARRAY_FILTER_USE_BOTH);
用 for 循环手动提取更可控
当数组很大、或需要避免创建中间闭包、或需兼容 PHP ARRAY_FILTER_USE_BOTH 从 5.6 起支持)时,for 是更稳妥的选择。
关键点是:必须用 isset() 或 key_exists() 判断键是否存在,不能只靠循环变量 $i —— 因为关联数组的键可能不连续。
立即学习“PHP免费学习笔记(深入)”;
- 对稀疏数组(如
[0 => 'a', 5 => 'b', 10 => 'c'])必须遍历键,而非假设索引连续 - 若确定是连续数字索引,可用
count()+for ($i = 0; $i - 提取时用
$result[$k] = $v保持键名,或$result[] = $v自动编号
用 array_keys() + array_intersect_key() 组合筛选
这个方法适合“先生成目标键列表,再批量取值”,逻辑分两步,可读性高,也便于复用键筛选逻辑。
缺点是:会多一次键提取和数组构造,内存略高;且对超大数组可能有性能损耗。
- 获取所有键:
$keys = array_keys($arr) - 筛选奇数位键(注意:这里是键在
$keys中的位置,不是原数组的键值!)→ 错误示范! - 正确做法:用
array_filter($keys, fn($k) => $k % 2 === 1)筛的是原数组的键本身(适用于键本身就是数字且你想按其奇偶筛) - 更安全的写法是先用
array_keys($arr, null, true)不推荐,易混淆;不如回到第一种array_filter方案
注意索引“奇偶”的实际含义:是键值,不是位置
这是最容易出错的地方。PHP 数组的“索引”指键名(key),不是元素在遍历中的顺序位置。比如:
$arr = [10 => 'x', 11 => 'y', 12 => 'z']; // 键 10 是偶数,11 是奇数,12 是偶数 // 但它们在 foreach 中的“第1个、第2个、第3个”是位置,不是键
所以筛选“偶数索引”得到的是 [10 => 'x', 12 => 'z'],不是前两个元素。
如果业务本意是“取第 0、2、4… 个遍历到的元素”,那得用计数器 + foreach,和键奇偶完全无关。











