Home » Php » php – array_walk_recursive – modify both keys and values

php – array_walk_recursive – modify both keys and values

Posted by: admin July 12, 2020 Leave a comment

Questions:

How can you modify both keys and values with array_walk_recursive??

Here only the values are encoded

function _utf8_encode($arr){
    array_walk_recursive($arr, 'utf8_enc');

    return $arr;
}

function utf8_enc(&$value, &$key){
    $value = utf8_encode($value);
    $key = utf8_encode($key);
}
How to&Answers:

array_walk_recursive does ONLY apply the user function on the VALUES of an array, not on indexes (I think it has something to with the fact, that the indexes of an array have to be unique, so you cannot manipulate them). Best thing would be to write a recursive function on yourself. The following should work:

function utf8enc($array) {
    if (!is_array($array)) return;
    $helper = array();
    foreach ($array as $key => $value) $helper[utf8_encode($key)] = is_array($value) ? utf8enc($value) : utf8_encode($value);
    return $helper;
}

$enc_array = utf8enc($your_array);

Answer:

This my recursive function that can change not only the values of the array as array_walk_recursive() but also the keys of the given array. It also keeps the order of the array.

/**
 * Change values and keys in the given array recursively keeping the array order.
 *
 * @param array    $_array    The original array.
 * @param callable $_callback The callback function takes 2 parameters (key, value)
 *                            and returns an array [newKey, newValue] or null if nothing has been changed.
 *
 * @return void
 */
function modifyArrayRecursive(array &$_array, callable $_callback): void
{
    $keys = \array_keys($_array);
    foreach ($keys as $keyIndex => $key) {
        $value = &$_array[$key];
        if (\is_array($value)) {
            modifyArrayRecursive($value, $_callback);
            continue;
        }

        $newKey = $key;
        $newValue = $value;
        $newPair = $_callback ($key, $value);
        if ($newPair !== null) {
            [$newKey, $newValue] = $newPair;
        }

        $keys[$keyIndex] = $newKey;
        $_array[$key] = $newValue;
    }

    $_array = \array_combine($keys, $_array);
}

/**
 * Usage example
 */
modifyArrayRecursive($keyboardArr, function ($key, $value) {
    if ($value === 'some value') {
        return ['new_key_for_this_value', $value];
    }

    return null;
});

Answer:

Another recursive function in addition to rabudde’s answer:

  function utf8_encode_array($array_to_encode=array()){

        $encoded_array=array();

        if(is_array($array_to_encode)){

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

                $key=utf8_encode($key);

                if(is_array($value)){

                    $encoded_array[$key]=utf8_encode_array($value);

                }
                else{

                    $encoded_array[$key]=utf8_encode($value);

                }
            }
        }

        return $encoded_array;
    }