PHP foreach() with arrays within arrays?

2019-01-14 23:21发布

I want to call a function on each element in an array. This is obviously very easy with a foreach(), but where I start breaking down is when arrays contain arrays. Can someone help me out with a function that will execute some code for every key -> value pair from a set of arrays within arrays. The depth could, in theory, be infinite, but a good limit would be 3 iterations (array in array in array) if recursion couldn't work.

An example array would be one taken from $_POST below:

Array
(
    [languages] => Array
    (
        [0] => php
        [1] => mysql
        [2] => inglip
    )

    [rates] => Array
    (
        [incall] => Array
        (
            [1hr] => 10
        )

        [outcall] => Array
        (
            [1hr] => 10
        )

    )
)

Just to make sure, what I want to do is run a piece of code (a function) that is passed every 'end node' in the array structure, so in the example above, it would be called when...

[0] => php
[1] => mysql
[2] => inglip
[1hr] => 10
[1hr] => 10

... is found.

Thanks for any help,

James

9条回答
看我几分像从前
2楼-- · 2019-01-14 23:26

See array_walk_recursive - a PHP library function that recursively calls a user defined function against a provided array.

From PHP docs:

<?php
$sweet = array('a' => 'apple', 'b' => 'banana');
$fruits = array('sweet' => $sweet, 'sour' => 'lemon');

function test_print($item, $key)
{
    echo "$key holds $item\n";
}

array_walk_recursive($fruits, 'test_print');
?>

Output:

a holds apple
b holds banana
sour holds lemon

Note that Any key that holds an array will not be passed to the function..

EDIT: slightly less ugly example:

<?php
$sweet = array('a' => 'apple', 'b' => 'banana');
$fruits = array('sweet' => $sweet, 'sour' => 'lemon');
array_walk_recursive($fruits, function ($item, $key) {
    echo "$key holds $item\n";
});
?>
查看更多
叛逆
3楼-- · 2019-01-14 23:27

Here's a simple reusable implementation:

function recursive_foreach($array, $callback) {
    foreach($array as $key => $value) {
        if (is_array($value)) {
            recursive_foreach($value, $callback);
        }
        else {
            call_user_func($callback, $key, $value);
        }
    }
}

Where $callback is a callback accepting two arguments: key and value. For example:

recursive_foreach($array, function($k, $v) {
    echo "$k => $v<br>";
});
查看更多
孤傲高冷的网名
4楼-- · 2019-01-14 23:28
function array_spelunk($array = array()) {
    foreach($array as $key => $node) {
        if (is_array($node)) {
            array_spelunk($node);
        } else {
           echo "[$key] [$node]\n";
        }
    }
}

array_spelunk($your_nested_array);
查看更多
Anthone
5楼-- · 2019-01-14 23:35

That's a perfect job for Iterators:

$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach($iterator as $key => $value) {
    echo "$key => $value\n";
}

See Introduction to SPL Iterators and Live Demo on codepad

EDIT: the alternative would be array_walk_recursive as show in Finbarr's answer below

查看更多
乱世女痞
6楼-- · 2019-01-14 23:37
function getEndNodes($input, $ret = array()) {

    foreach ($input as $key => $value) {
        if (!is_array($input[$key])) {
            $ret[$key] = $value;
        } else {
            $ret = getEndNodes($input[$key],$ret);
        }
    }

    return $ret;

}


// Usage: 
$endNodes = getEndNodes($yourarray);
查看更多
成全新的幸福
7楼-- · 2019-01-14 23:39
function recurse($element, $key = null) {
  if(is_array($element)) {
    foreach($element as $k => $v) {
      recurse($v, $k);
    }
  }else{
    //Do what you want here. $element is value, $key is the key
  } 
}
查看更多
登录 后发表回答