views:

11

answers:

2

Often, I will have an array holding a set of values each of which I need to process. Sometimes, the array will only hold a single set, in which case each value needs to be put through the process. Other times, the array will hold many sets, in which case each value will be an array and each value of those arrays will need to be processed. Here is an example:

foreach($array as $key => $value) {
    if(is_array($value)) {
        foreach($value as $subkey => $subvalue) {
            //Process $subvalue here    
        }
    }
    else {
        //Process $value here
    }
}

The problem is that the code for processing $value/$subvalue is identical except that it operates on a different variable. One way to simplify this would be to put that code into a function but it still seems inelegant to have to call it twice. Furthermore, that would leave quite a lot of code (the foreach loops and array test) outside of that function. For example, say the process is validation, I don't want to have to write two foreach loops and an array test whenever I want to call my validation function.

Is there a simpler way of doing this?

+1  A: 

Wrap the single value into an array, then proceed as usual:

foreach($array as $key => $value) {

    if(!is_array($value)) $value = array($value);

    foreach($value as $subkey => $subvalue) {
        //Process $value/$subvalue here    
    }
}

Alternatively you can create a function that handles the processing of single items, then call that same function from each branch. You'll still end up saving writing the process twice.

Tatu Ulmanen
Great idea! Instead of testing for an array, would it be better/simpler to do type casting? In other words, instead of the if statement, just put $value = (array) $value; Nothing would happen if $value were already an array, otherwise it becomes an array.
Rupert
@Rupert, that's a great idea also, that essentially accomplishes the same thing in less space (and possibly faster if that would be an issue). :)
Tatu Ulmanen
+1  A: 

You can use a RecursiveArrayIterator to iterate over the values in the array, e.g.

$iterator = new RecursiveIteratorIterator(
                new RecursiveArrayIterator($yourArray),
                RecursiveIteratorIterator:SELF_FIRST);

Then just foreach over it. Further reading:

Gordon