Php 是否从多维数组中删除深度嵌套的元素?
我需要从未知结构的深度嵌套数组中删除一个元素(也就是说,我不知道为取消设置该元素而寻址该元素的键序列是什么)。但是,我要删除的元素有一个一致的结构(stdObject),因此我可以搜索整个多维数组来找到它,但是必须删除它。关于如何做到这一点的想法 编辑:这是我目前正在尝试实现的功能Php 是否从多维数组中删除深度嵌套的元素?,php,arrays,search,Php,Arrays,Search,我需要从未知结构的深度嵌套数组中删除一个元素(也就是说,我不知道为取消设置该元素而寻址该元素的键序列是什么)。但是,我要删除的元素有一个一致的结构(stdObject),因此我可以搜索整个多维数组来找到它,但是必须删除它。关于如何做到这一点的想法 编辑:这是我目前正在尝试实现的功能 function _subqueue_filter_reference(&$where) { foreach ($where as $key => $value) { if (i
function _subqueue_filter_reference(&$where)
{
foreach ($where as $key => $value) {
if (is_array($value))
{
foreach ($value as $filter_key => $filter)
{
if (isset($filter['field']) && is_string($filter['field']) && $filter['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference')
{
unset($value[$filter_key]);
return TRUE;
}
}
return _subqueue_filter_reference($value);
}
}
return FALSE;
}
编辑#2:从var#u dump
截取数组结构
array (size=1)
1 =>
array (size=3)
'conditions' =>
array (size=5)
0 =>
array (size=3)
...
1 =>
array (size=3)
...
2 =>
array (size=3)
...
3 =>
array (size=3)
...
4 =>
array (size=3)
...
'args' =>
array (size=0)
empty
'type' => string 'AND' (length=3)
…因此,假设将整个结构分配给$array
,我需要删除的元素是$array[1]['conditions'][4]
,其中目标是一个包含三个字段的数组:
- 场
- 价值观
- 接线员
…所有这些都是字符串值。解决此问题的一种方法是使用第二个参数扩展递归函数:
function _subqueue_filter_reference(&$where, $keyPath = array())
您仍然会以相同的方式进行初始调用,但对自身的内部调用如下:
return _subqueue_filter_reference($value, array_merge($keyPath, array($key)));
这将为您提供键的完整路径,以到达$keyPath
变量中数组的当前部分。然后,您可以在取消设置中使用此选项。如果你觉得自己很脏,你甚至可以使用eval
作为一个有效的快捷方式,因为输入的来源完全在你的控制范围内
编辑:另一方面,在数组上循环时从数组中删除项目可能不是一个好主意。我不确定foreach是如何编译的,但如果您遇到奇怪的错误,您可能需要将查找逻辑与删除逻辑分开。这只是光标问题
function recursive_unset(&$array)
{
foreach ($array as $key => &$value) # See the added & here.
{
if(is_array($value))
{
if(isset($value['field']) && $value['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference')
{
unset($array[$key]);
}
recursive_unset($value);
}
}
}
注意:这里不需要使用is_字符串,只需在与字符串进行比较且值存在时进行比较即可
除非您确定您的值只出现一次,否则不要使用return
编辑:
下面是一个完整的示例,其数组与您展示的类似:
$test = array (
1 => array (
'conditions' =>
array (
0 => array ('field' => 'dont_care1', 'value' => 'test', 'operator' => 'whatever'),
1 => array ('field' => 'dont_care2', 'value' => 'test', 'operator' => 'whatever'),
2 => array ('field' => 'nodequeue_nodes_node__nodequeue_subqueue.reference', 'value' => 'test', 'operator' => 'whatever'),
3 => array ('field' => 'dont_care3', 'value' => 'test', 'operator' => 'whatever')
),
'args' => array (),
'type' => 'AND'
));
var_dump($test);
function recursive_unset(&$array)
{
foreach ($array as $key => &$value)
{
if(is_array($value))
{
if(isset($value['field']) && $value['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference')
{
unset($array[$key]);
}
recursive_unset($value);
}
}
}
recursive_unset($test);
var_dump($test);
我已经找到了一个解决方案,它是(array\u search
documentation)中的函数的衍生产品
代码:
我讨厌使用eval,因为它会造成巨大的、巨大的安全漏洞,但它非常安全,eval中调用的值是由Drupal核心和视图显式生成的。我现在可以用它了
无论如何,当我返回树时,我只是用新返回的树数组替换旧数组。工作起来很有魅力。我已经读过这篇文章,但它没有回答我的问题。如果我知道深嵌套元素的确切键序列,那么使用unset
将很容易,但是我不知道。你知道你必须搜索它。所以当你发现它时,用unset。也许我不明白。搜索并删除…对吗?刚刚在三维数组上测试了这段代码,它成功了。但是,如果“字段”位于数组的第一级,它将不起作用(不会删除数组本身)。我添加了正在搜索的数组结构示例。编辑以显示完整的代码。仍然适用于我的采样阵列。也许可以展示你所做代码的实现?将是比评估更好的解决方案。
function _subqueue_filter_reference($haystack,&$tree=array(),$index="")
{
// dpm($haystack);
if (is_array($haystack))
{
$result = array();
if (count($tree)==0)
{
$tree = array() + $haystack;
}
foreach($haystack as $k=>$current)
{
if (is_array($current))
{
if (isset($current['field']) && is_string($current['field']) && $current['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference')
{
eval("unset(\$tree{$index}[{$k}]);"); // unset all elements = empty array
}
_subqueue_filter_reference($current,$tree,$index."[$k]");
}
}
}
return $tree;
}