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

时间:2015-09-03 22:25:50

标签: php arrays iterator

我有一个包含可变数量级别数据的多维数组。也就是说,我无法确定到达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保持的数组)并查看该数组是否包含值{{ 1}}。

如果在数组中找到Foo,我需要添加一个新值(除了Foo - 所以称之为Foo)到数组然后继续,因为父数组中可能有更多Bar

有没有办法在我们找到Goals时“停止”迭代器,而不进一步迭代,然后执行Goal操作?

编辑:沿着这些方向尝试一些事情 -

array_search

3 个答案:

答案 0 :(得分:1)

不完全确定这是否是您想要实现的目标,但这是一个将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',
    ),
  ),
)

答案 1 :(得分:0)

在我看来,迭代器在这些数组中使用会很奇怪......我会这样做:

/*
    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;
}

答案 2 :(得分:0)

我同意递归是这样做的方法。使用array_walk_recursive的问题在于,您将无法看到Goal密钥,因为根据PHP documentation

  

任何包含数组的键都不会传递给函数。

我不确定使用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的副本。