我需要从一个深层嵌套的未知结构数组中删除一个元素(即我不知道为了取消它而解决该元素的键序列是什么)。但是我删除的元素确实具有一致的结构(stdObject),因此我可以搜索整个多维数组来查找它,但是必须将其删除。关于如何做到这一点的想法?
编辑:这是我现在正在努力实现的功能。
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_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]
,其中该目标是一个包含三个字段的数组:
...所有这些都是字符串值。
答案 0 :(得分:0)
解决此问题的一种方法是使用第二个参数扩展递归函数:
function _subqueue_filter_reference(&$where, $keyPath = array())
你仍然以同样的方式进行初始调用,但内部调用本身就是这样:
return _subqueue_filter_reference($value, array_merge($keyPath, array($key)));
这将为您提供到达$keyPath
变量中数组当前部分的完整键路径。然后,您可以在unset
中使用此功能。如果你感觉很脏,你甚至可以使用eval
作为有效的快捷方式,因为你给它的输入源完全在你的控制之内。
编辑:另外请注意,在循环播放数据时,从数组中删除项目可能不是一个好主意。我不确定foreach如何编译,但如果你得到奇怪的错误,你可能想要将你的发现逻辑与删除逻辑分开。
答案 1 :(得分:0)
这只是一个游标问题。
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_string,你可以在比较字符串时进行比较并且值存在。
除非您确定只有一次出现您的价值,否则请勿使用退货。
修改:
这是一个完整的示例,其数组与您展示的类似:
$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);
答案 2 :(得分:0)
我已经找到了一个解决方案,该解决方案是http://www.php.net/manual/en/function.array-search.php#79535(array_search
文档)中找到的函数的衍生产品。
代码:
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;
}
我讨厌必须使用eval作为一个巨大的,巨大的安全漏洞的SCREAMS,但它非常安全,并且eval中调用的值由Drupal核心和Views显式生成。我现在可以使用它了。
无论如何,当我返回树时,我只需用新返回的树数组替换旧数组。像魅力一样。