我有一个多维数组,其中包含可变数量的数据级别。也就是说,我不能确定需要多少次迭代才能达到Goal
级别,这是一个数组。像这样:
[
'key1' = 'value1',
'key2' = 'value2',
'key3' = [
'key4' => [
'key5' => 'value3'
],
'key6' => 'value4'
],
'key7' => [
'Goal' => [
'value5',
'value6',
'value7'
]
],
'key8' => 'value8'],
'key9' => [
'Goal' => [
'value9',
'Foo',
'value10'
]
]
]
我试过array_walk_recursive
和ArrayIterator
,但似乎都没有让我在我需要的地方。
我需要遍历数组的每个元素,如果键是Goal
检查值(例如。(Goal
保存的数组),并查看该数组是否包含值Foo
。
如果在数组中找到Foo
,我需要向数组添加一个新值(除了Foo
——所以称之为Bar
),然后继续,因为父数组中可能有更多的Goals
。
当我们找到Goal
时,是否有一种方法可以"停止"迭代器,而不进一步迭代,然后进行array_search
操作?
编辑:沿着这些线尝试一些东西——
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach($iterator as $key => $value)
{
if($key == 'Goal')
{
if (is_array($value)) {
if(array_search('Foo', $value)) {
$value[] = 'Bar';
}
}
}
}
不完全确定这是否是您想要实现的,但这里有一个解决方案,将Bar
添加到嵌套在Goal
键中的数组:
$array = [
'key1' => 'value1',
'key2' => 'value2',
'key3' => [
'key4' => [
'key5' => 'value3',
],
'key6' => 'value4',
],
'key7' => [
'Goal' => [
'value5',
'value6',
'value7',
],
],
'key8' => 'value8',
'key9' => [
'Goal' => [
'value9',
'Foo',
'value10',
],
],
];
function iterate(array $data, $goal = false)
{
foreach ($data as $key => &$value) {
if (is_array($value)) {
$value = iterate($value, $key === 'Goal');
} elseif (is_string($value)) {
if (($value === 'Foo') && $goal) {
$data[] = 'Bar';
return $data;
}
}
}
return $data;
}
var_export(iterate($array));
代码生成如下输出:
array (
'key1' => 'value1',
'key2' => 'value2',
'key3' =>
array (
'key4' =>
array (
'key5' => 'value3',
),
'key6' => 'value4',
),
'key7' =>
array (
'Goal' =>
array (
0 => 'value5',
1 => 'value6',
2 => 'value7',
),
),
'key8' => 'value8',
'key9' =>
array (
'Goal' =>
array (
0 => 'value9',
1 => 'Foo',
2 => 'value10',
3 => 'Bar',
),
),
)
在我看来,在这类数组中使用迭代器会很奇怪…我会这样做:
/*
Usage:
$wasFound = checkArray( "Goal", "Foo", $the_array);
if ( $wasFound ) echo "Key and Value pair found in the array!";
else { /* not found */ }
*/
function checkArray( $key_to_find, $value_to_find, $my_var, $last_key = NULL ) {
$found = FALSE;
if ( $last_key == $key_to_find && $my_var == $value_to_find )
return TRUE;
if ( $my_var == NULL )
return FALSE;
if ( is_array( $my_var ) ) {
foreach ( $my_var AS $key => $value )
{
if ( $found ) {
/* Do something else if needed when found */
break;
}
$found = checkArray( $key_to_find, $value_to_find, $value, $key );
}
}
return $found;
}
我同意递归是做到这一点的方法。使用array_walk_recursive
的问题是,您将无法看到Goal
键,因为根据PHP文档,
任何保存数组的键都不会传递给函数。
我不确定是否使用RecursiveIteratorIterator
会比为它写一个递归函数更好。这样的函数应该相当简单。
function addBar(&$array) {
foreach ($array as $key => &$value) {
if ($key === 'Goal') {
if(array_search('Foo', $value)) {
$value[] = 'Bar';
}
} elseif (is_array($value)) {
addBar($value);
}
}
}
该函数接受对数组的引用,因此它将更新实际的数组,而不是创建一个副本,将Bar
添加到每个Goal
。