简单的键白名单过滤器
<?php
$arr = array('a' => 123, 'b' => 213, 'c' => 321);
$allowed = array('b', 'c');
print_r(array_intersect_key($arr, array_flip($allowed)));
?>
将返回
数组
(
[b] => 213
[c] => 321
)
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
array_intersect_key — 使用键进行比较来计算数组的交集
array_intersect_key() 返回一个数组,其中包含 array
中所有在所有参数中都存在的键的条目。
array
要检查的主键的数组。
arrays
要比较键的数组。
返回一个关联数组,其中包含 array
中所有在所有参数中都存在的键的条目。
版本 | 描述 |
---|---|
8.0.0 | 此函数现在可以只使用一个参数调用。以前,至少需要两个参数。 |
示例 #1 array_intersect_key() 示例
<?php
$array1 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8);
var_dump(array_intersect_key($array1, $array2));
?>
以上示例将输出
array(2) { ["blue"]=> int(1) ["green"]=> int(3) }
在我们的示例中,您可以看到只有键 'blue'
和 'green'
出现在两个数组中,因此被返回。还要注意,键 'blue'
和 'green'
的值在这两个数组中有所不同。仍然会发生匹配,因为只检查键。返回的值是 array
的值。
只有当 (string) $key1 === (string) $key2
时,key => value
对中的两个键才被认为相等。换句话说,执行严格的类型检查,因此字符串表示必须相同。
简单的键白名单过滤器
<?php
$arr = array('a' => 123, 'b' => 213, 'c' => 321);
$allowed = array('b', 'c');
print_r(array_intersect_key($arr, array_flip($allowed)));
?>
将返回
数组
(
[b] => 213
[c] => 321
)
请注意,返回数组中键的顺序与源数组中键的顺序相同。
要按第二个数组排序,您可以通过 array_replace 进行排序。
<?php
$array = array(
'two' => 'a',
'three' => 'b',
'one' => 'c',
);
$keyswant = array(
'one' => '',
'three' => '',
);
print_r(array_intersect_key(array_replace($keyswant, $array), $keyswant));
?>
显示
数组
(
[one] => c
[three] => b
)
而不是
数组
(
[three] => b
[one] => c
)
[编辑注:将 array_merge_recursive() 更改为 array_replace_recursive() 以修复脚本]
这是一种使用某些默认值作为白名单来合并设置的更好方法。
<?php
$defaults = [
'id' => 123456,
'client_id' => null,
'client_secret' => null,
'options' => [
'trusted' => false,
'active' => false
]
];
$options = [
'client_id' => 789,
'client_secret' => '5ebe2294ecd0e0f08eab7690d2a6ee69',
'client_password' => '5f4dcc3b5aa765d61d8327deb882cf99', //忽略
'client_name' => 'IGNORED', //忽略
'options' => [
'active' => true
]
];
var_dump(
array_replace_recursive($defaults,
array_intersect_key(
$options, $defaults
)
)
);
?>
输出
数组 (大小:4)
'id' => 整数 123456
'client_id' => 整数 789
'client_secret' => 字符串 '5ebe2294ecd0e0f08eab7690d2a6ee69' (长度:32)
'options' =>
数组 (大小:2)
'trusted' => 布尔值 false
'active' => 布尔值 true
注意,返回数组中键的顺序与源数组中键的顺序相同,例如:
<?php
$array = array(
'two' => 'a',
'three' => 'b',
'one' => 'c',
);
$keyswant = array(
'one' => '',
'three' => '',
);
print_r(array_intersect_key($array, $keyswant));
?>
显示
数组
(
[three] => b
[one] => c
)
我发现以下内容很有帮助
<?PHP
function array_merge_default($default, $data) {
$intersect = array_intersect_key($data, $default); //获取存在默认值的数据
$diff = array_diff_key($default, $data); //获取数据中不存在的默认值
return $diff + $intersect; //数组具有不同的键,返回两者的并集
}
?>
它的用法与它使用的两个函数都类似,但它保留默认值并且_只有_默认值。它专为键数组设计,我不确定它在数字索引数组上的工作方式。
示例
<?PHP
$default = array(
"one" => 1,
"two" => 2
);
$untrusted = array(
"one" => 42,
"three" => 3
);
var_dump(array_merge_default($default, $untrusted));
array(2) {
["two"]=>
int(2)
["one"]=>
int(42)
}
?>
Jesse:不,array_intersect_key无法实现你发布的相同功能
array_flip (array_intersect (array_flip ($a), array_flip ($b)))
因为当数组被翻转时,值变成了键。具有重复值不是问题,但具有重复键是问题。array_flip通过只保留一个重复项并丢弃其余项来解决此问题。当你开始相交时,你已经丢失了信息。
关于php at keithtylerdotcom 模拟的解决方案
<?php
$z = someFuncReturningAnArray()['some_key'];
?>
他推荐的解决方案仍然会返回一个数组。要获取函数返回的数组中单个键的值,只需向配方中添加implode()
<?php
function someFuncReturningAnArray() {
return array(
'a' => 'b',
'c' => 'd',
'e' => 'f',
'g' => 'h',
'i' => 'j'
);
}
//传统方法
$temp = someFuncReturningAnArray();
$b = $temp['a'];
echo print_r($b, 1) . "\n----------\n";
//keithtylerdotcom 单行方法
$b = array_intersect_key(someFuncReturningAnArray(), array('a'=>''));
echo print_r($b, 1) . "\n----------\n";
//更好的单行方法
$b = implode('', array_intersect_key(someFuncReturningAnArray(), array('a'=>'')));
echo print_r($b, 1) . "\n----------\n";
?>
<?php
/**
* 计算两个数组的交集,类似于 array_intersect_key 但递归
*
* @param array/mixed 主数组
* @param array 具有应保留在主数组中的键的数组
* @return array/mixed 清理后的主数组
*/
function myIntersect($master, $mask) {
if (!is_array($master)) { return $master; }
foreach ($master as $k=>$v) {
if (!isset($mask[$k])) { unset ($master[$k]); continue; } //如果键不存在于 $mask 中,则从 $master 中移除值
if (is_array($mask[$k])) { $master[$k] = $this->myIntersect($master[$k], $mask[$k]); } //当 mask 是数组时递归
//否则只保留值
}
return $master;
}
?>
如果你在这里寻找一个返回包含所有具有相交键的数组值的数组的函数
<?php
function array_merge_on_key($key, $array1, $array2) {
$arrays = array_slice(func_get_args(), 1);
$r = array();
foreach($arrays as &$a) {
if(array_key_exists($key, $a)) {
$r[] = $a[$key];
continue;
}
}
return $r;
}
// 示例:
$array1 = array("id" => 12, "name" => "Karl");
$array2 = array("id" => 4, "name" => "Franz");
$array3 = array("id" => 9, "name" => "Helmut");
$array4 = array("id" => 10, "name" => "Kurt");
$result = array_merge_on_key("id", $array1, $array2, $array3, $array4);
echo implode(",", $result); // => 12,4,9,10
?>
如果您想使用仅包含零和一的数组作为另一个数组的掩码(当然,这两个数组必须具有相同的大小),这是一个简单的脚本。`$outcome` 是一个数组,它只包含 `$source` 中 `$mask` 等于 1 的那些值。
<?php
$outcome = array_values(array_intersect_key( array_values($source), array_filter(array_values($mask)) ));
?>
PS:`array_values()` 函数是必要的,以确保两个数组具有相同的编号/键,否则您的掩码不会按预期工作。
享受!