我希望能够通过key
此类数组的示例可以是:
Array
(
[data] => Array
(
[todo] => code review
[schedule] => Array
(
[endDate] => 2019-05-10T00:00:00+01:00
[startDate] => 2019-05-09T00:00:00+01:00
)
[codeDetails] => Array
(
[language] => PHP
[type] => class
[abstract] => true
[methodCount] => Array
(
[public] => 3
[protected] =>
[private] => 1
)
[LOC] => 123
[cyclomaticComplexity] => 4
[author] => Array (
[name] => Lukasz
[email] => private@tulik.io
)
)
)
)
我有两种方法,recursiveArrayDelete
删除回调返回true
的所有元素:
private function recursiveArrayDelete(array &$array, callable $callback): array
{
foreach ($array as $key => &$value) {
if (is_array($value)) {
$value = $this->recursiveArrayDelete($value, $callback);
}
if ($callback($value, $key)) {
unset($array[$key]);
}
}
return $array;
}
第二,从restrictedProperties
中删除array
中所有包含的属性:
private function sanitizedArray(array &$array, array &$restrictedProperties): array
{
foreach ($restrictedProperties as $restrictedProperty) {
$this->recursiveArrayDelete(
$array,
static function () use ($array, $restrictedProperty): bool {
array_walk_recursive(
$array,
static function ($value, $key) use (&$bool, $restrictedProperty) {
// here $bool is as expected from condition
$bool = $key === $restrictedProperty;
});
// here is alwalys false
return $bool;
});
}
return $array;
}
用法示例:
$this->sanitizedResponse($data, ['methodCount', `endDate`]);
应从数组中删除这些元素。但正如我在com {sanitizedArray
一文中提到的,其中return $bool;
总是产生false
答案 0 :(得分:2)
您做得很好。注意,您有两个问题:首先在两个函数中都进行递归,然后重新分配给$bool
-因此只有最后一个比较才是计数(这就是为什么总是出现错误的原因)。
我将通过以下方式使您的代码更简单:
function array_filter_recursive(array &$array, callable $callback) {
foreach ($array as $key => &$value) {
if ($callback($key, $value)) unset($array[$key]);
else if (is_array($value)) array_filter_recursive($value, $callback);
}
}
function sanitizedArray(&$arr, $restricted, $keys = false) {
foreach($restricted as $val) {
array_filter_recursive($arr, function($k, $v) use ($val, $keys) {return $keys ? ($val === $k) : ($val === $v);});
}
}
现在您可以简单地将其用作示例:$this->sanitizedResponse($data, ['methodCount', 'endDate'], true);
以下是带有伪数据的实时示例:3v4l
答案 1 :(得分:2)
@dWinder的答案几乎是完美的。但是,当我使用它的时候多了一点,我注意到它不会不删除给定“受限属性”下的数组。
让我们假设所有"D"
元素都将被删除:
dWinder的解决方案将导致:
Array
(
[A] => aa
[B] => Array
(
[A] => aaa
[B] => bb
)
[C] => cc
[D] => Array
(
[E] => ee
)
)
"D"
下的数组仍然存在。但是,当您将if
的条件和动作切换为else if
的条件和动作时,会得到(假定!)所需的结果:
Array
(
[A] => aa
[B] => Array
(
[A] => aaa
[B] => bb
)
[C] => cc
)
因此,改进的功能代码应如下所示(我在这里引用@dWinder解决方案的某些部分):
$arr = array("A" => "aa", "B" => ["A" => "aaa", "B" => "bb"], "C" => "cc", "D" => ["E" =>"ee"]);
function array_filter_recursive(array &$array, callable $callback) {
foreach ($array as $key => &$value) {
if ($callback($key, $value)) unset($array[$key]);
else if (is_array($value)) array_filter_recursive($value, $callback);
}
}
function sanitizedArray(&$arr, $restrictedProperties) {
foreach($restrictedProperties as $prop) {
array_filter_recursive($arr, function($k, $v) use ($prop) {return $prop == $k;});
}
}
sanitizedArray($arr, ["D"]);
print_r($arr);
参见此处的演示:https://3v4l.org/05tc7