使用PHP数组迭代器编辑数组


Using PHP array iterator to edit array

我有一个多维数组,其中包含可变数量的数据级别。也就是说,我不能确定需要多少次迭代才能达到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_recursiveArrayIterator,但似乎都没有让我在我需要的地方。

我需要遍历数组的每个元素,如果键是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