我创建了一个函数来方便将
array_diff()
与两个二维数组一起使用,但这还不够。
<?php
$arraySession = array(
'sampleA' => array('1', '2', '3'),
'sampleB' => array('1', '2', '3'),
);
$arrayPost = array(
'sampleA' => array('1'),
'sampleB' => array('1', '2'),
);
结果应该是:
array(
'sampleA' => array('2', '3')
'sampleB' => array('3'),
)
我现有的功能:
public function array_diff_multidimensional($session, $post) {
$result = array();
foreach ($session as $sKey => $sValue) {
foreach ($post as $pKey => $pValue) {
if ((string) $sKey == (string) $pKey) {
$result[$sKey] = array_diff($sValue, $pValue);
} else {
$result[$sKey] = $sValue;
}
}
}
return $result;
}
不是我的功能,也没有经过我的测试,但这是 php.net/array_diff 上的第一批评论之一(归功于 gmail dot com 的 thefrox)
<?php
function multidimensional_array_diff($a1, $a2) {
$r = array();
foreach ($a2 as $key => $second) {
foreach ($a1 as $key => $first) {
if (isset($a2[$key])) {
foreach ($first as $first_value) {
foreach ($second as $second_value) {
if ($first_value == $second_value) {
$true = true;
break;
}
}
if (!isset($true)) {
$r[$key][] = $first_value;
}
unset($true);
}
} else {
$r[$key] = $first;
}
}
}
return $r;
}
?>
这应该可以做到,假设所有键都出现在两个数组中:
$diff = array();
foreach ($session as $key => $values) {
$diff[$key] = array_diff($values, $post[$key]);
}
或者,因为我很无聊并且
array_map
没有得到充分利用:
$diff = array_combine(
array_keys($session),
array_map(function ($a, $b) { return array_diff($a, $b); }, $session, $post)
);
(假设数组有序。)
你想要或多或少像这样的东西:
public function array_diff_multidimensional($arr1, $arr2) {
$answer = array();
foreach($arr1 as $k1 => $v1) {
// is the key present in the second array?
if (!array_key_exists($k1, $arr2)) {
$answer[$k1] = $v1;
continue;
}
// PHP makes all arrays into string "Array", so if both items
// are arrays, recursively test them before the string check
if (is_array($v1) && is_array($arr2[$k1])) {
$answer[$k1] = array_diff_multidimensional($v1, $arr2[$k1]);
continue;
}
// do the array_diff string check
if ((string)$arr1[$k1] === (string)$arr2[$k1]) {
continue;
}
// since both values are not arrays, and they don't match,
// simply add the $arr1 value to match the behavior of array_diff
// in the PHP core
$answer[$k1] = $v1;
}
// done!
return $answer;
}
array_reduce()
可用于执行基于行的过滤并保留第一级关联键。在下面的脚本中,使用数组联合运算符 (+
) 将新的关联元素推入结果数组中。 演示
$arraySession = [
'sampleA' => ['1', '2', '3'],
'sampleB' => ['1', '2', '3'],
];
$arrayPost = [
'sampleA' => ['1'],
'sampleB' => ['1', '2'],
];
var_export(
array_reduce(
array_keys($arraySession),
fn($result, $k) => $result
+ [$k => array_diff($arraySession[$k], $arrayPost[$k] ?? [])],
[]
)
);
输出:
array (
'sampleA' =>
array (
1 => '2',
2 => '3',
),
'sampleB' =>
array (
2 => '3',
),
)
@deceze 已经演示了使用
foreach
循环的等效效果。 如果 post 数组可能不包含会话数组中存在的所有键,则回退到空数组或完全跳过 array_diff()
调用。 演示
$result = [];
foreach ($arraySession as $k => $row) {
$result[$k] = array_diff($row, $arrayPost[$k] ?? []);
}
var_export($result);
在 foreach 循环中通过引用修改行将无法正常工作。 演示
$result = [];
foreach ($arraySession as $k => &$row) {
$row = array_diff($row, $arrayPost[$k] ?? []);
}
var_export($result);