Php 使用数组\u walk\u递归但拒绝特定值的筛选器数组
我正在尝试筛选数组Php 使用数组\u walk\u递归但拒绝特定值的筛选器数组,php,recursion,filter,Php,Recursion,Filter,我正在尝试筛选数组 $array = [ [ 'id' => 1, 'some_key' => 'some_value', 'attribute' => [ 'id' => 45, 'cat_id' => 1 ], 'sub' => [ 'id' => 17, 'some_
$array = [
[
'id' => 1,
'some_key' => 'some_value',
'attribute' => [
'id' => 45,
'cat_id' => 1
],
'sub' => [
'id' => 17,
'some_key' => 'some_value',
'attribute' => [
'id' => 47,
'cat_id' => 17
],
],
],
[
'id' => 2,
'some_key' => 'some_value',
'sub' => [
'id' => 19,
'some_key' => 'some_value',
],
]
];
$childArray = [];
array_walk_recursive($array, static function($value, $key) use(&$childArray){
if($key === 'id') {
$childArray[] = $value;
}
});
这将返回一个包含所有以id为键的数组字段的数组
但是有一个小问题,一些数组有一个名为attribute的键,其中包含一个我不想要的idkey字段
[1,17,2,19] //this is what I want
有没有一种方法可以说不要在属性中使用id
在我当前的解决方案中,我在过滤器之前添加了一个过滤器:D
但这似乎不是最佳实践^^您可以手动递归遍历,而不是递归遍历数组,并避免在属性键下进行所有遍历
演示:您可以手动递归遍历,而不是递归遍历数组,并避免属性键下的所有遍历
演示:找到一个可以展平阵列的函数。结果应该是这样的我有一个这样的类:
array (
0 =>
array (
'id' => 1,
'some_key' => "some_value",
'attribute.id' => 45,
'attribute.cat_id' => 1,
'sub.id' => 17,
'sub.some_key' => "some_value",
'sub.attribute.id' => 47,
'sub.attribute.cat_id' => 17,
),
1 =>
array (
'id' => 2,
'some_key' => "some_value",
'sub.id' => 19,
'sub.some_key' => "some_value",
),
)
因此,您拥有所有可用的密钥,并且可以使用修改后的数组。\u walk
$childArray = [];
array_walk_recursive($data, static function($value, $key) use(&$childArray){
$keys = array_reverse(explode(".",$key));
if($keys[0] === 'id' AND (!isset($keys[1]) OR $keys[1] != 'attribute')) {
$childArray[] = $value;
}
});
递归ArrayIterator类在数组值将根据键和值收集在不同层次上
$result = [];
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach($it as $key => $value) {
$parentLevel = $it->getDepth()-1;
$parentKey = $it->getSubIterator($parentLevel)->key();
if($key === 'id' AND $parentKey !== 'attribute'){
$result[] = $value;
}
}
var_export($result);
//array ( 0 => 1, 1 => 17, 2 => 2, 3 => 19, )
找到一个可以展平阵列的函数。结果应该是这样的我有一个这样的类:
array (
0 =>
array (
'id' => 1,
'some_key' => "some_value",
'attribute.id' => 45,
'attribute.cat_id' => 1,
'sub.id' => 17,
'sub.some_key' => "some_value",
'sub.attribute.id' => 47,
'sub.attribute.cat_id' => 17,
),
1 =>
array (
'id' => 2,
'some_key' => "some_value",
'sub.id' => 19,
'sub.some_key' => "some_value",
),
)
因此,您拥有所有可用的密钥,并且可以使用修改后的数组。\u walk
$childArray = [];
array_walk_recursive($data, static function($value, $key) use(&$childArray){
$keys = array_reverse(explode(".",$key));
if($keys[0] === 'id' AND (!isset($keys[1]) OR $keys[1] != 'attribute')) {
$childArray[] = $value;
}
});
递归ArrayIterator类在数组值将根据键和值收集在不同层次上
$result = [];
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach($it as $key => $value) {
$parentLevel = $it->getDepth()-1;
$parentKey = $it->getSubIterator($parentLevel)->key();
if($key === 'id' AND $parentKey !== 'attribute'){
$result[] = $value;
}
}
var_export($result);
//array ( 0 => 1, 1 => 17, 2 => 2, 3 => 19, )
要返回符合条件的ID而不是创建引用变量,请在迭代时合并函数的递归调用 代码: 输出:
array (
0 => 1,
1 => 17,
2 => 2,
3 => 19,
)
要返回符合条件的ID而不是创建引用变量,请在迭代时合并函数的递归调用 代码: 输出:
array (
0 => 1,
1 => 17,
2 => 2,
3 => 19,
)
使用array_walk_recursive很难做到这一点,因为它只访问叶键值。使用array_walk_recursive很难做到这一点,因为它只访问叶键值。这个解决方案的想法很好,但这会迫使我在数组中运行几次。这正是我想要避免的:但是思想还是+1,赞美还是+1。如今,编写可理解的代码比在执行时节省一微秒更重要。我添加了一个变体。我喜欢看到总是有几种方法来实现罗马:D使用迭代器也是一种很好的可能性。这个解决方案的想法很好,但这会迫使我在数组中运行几次。这正是我想要避免的:但是思想还是+1,赞美还是+1。如今,编写可理解的代码比在执行时节省一微秒更重要。我添加了一个变体。我喜欢看到总是有几种方法可以到达罗马:D使用迭代器也是一种很好的可能性。