Monday, May 7, 2012

Does PHP have an array_map_recursive function that gives my callback access to the array's keys?

No. However, you can add this functionality to your project via the following code:
<?php
function array_map_recursive(Array &$arr, $fnMap)
{
    $fnHelper = function (Array $arr, $fnMap, $fnHelper)
    {
        $result = array();
        foreach ($arr as $key => $value)
        {
            if (is_array($value))
            {
                $fnMap($key, $null = NULL, $isKeyOnly = TRUE);
                $result[$key] = $fnHelper($value, $fnMap, $fnHelper);
                continue;
            }
            $fnMap($key, $value, $isKeyOnly = FALSE);
            $result[$key] = $value;
        }
        return $result;
    };
    $arr = $fnHelper($arr, $fnMap, $fnHelper);
}
Note that array_walk_recursive provides similar functionality but falls short of our requirements due to the following caveat copy and pasted directly from php.net:
"You may notice that the key 'sweet' is never displayed. Any key that holds an array will not be passed to the function."
Example usage would look like:
<?php
// EXAMPLE CALLBACK
$urldecode = function (&$key, &$value, $isKeyOnly) // NOTE THE 3 ARGS AND THE FACT THAT THE FIRST TWO ARE BY REF
{
    $key = urldecode($key);
    $value = urldecode($value);
};

// EXAMPLE DATA
$data = array(
    '%21' => '%21',
    '%40' => '%40',
    '%23' => array(
        '1' => '%23',
        '3' => '%23',
        '2' => '%23',
    ),
    '%24' => '%24',
    '%25' => '%25',
    '%5E' => '%5E',
    '%26' => '%26',
    '%2A' => '%2A',
);

// DEMO...
echo "BEFORE:\n";
print_r($data);
array_map_recursive($data, $urldecode);
echo "\nAFTER:\n";
print_r($data);

/*
THE EXAMPLE CODE ABOVE OUTPUTS:

BEFORE:
Array
(
    [%21] => %21
    [%40] => %40
    [%23] => Array
    (
        [1] => %23
        [3] => %23
        [2] => %23
    )
    [%24] => %24
    [%25] => %25
    [%5E] => %5E
    [%26] => %26
    [%2A] => %2A
)

AFTER:
Array
    (
    [!] => !
    [@] => @
    [#] => Array
    (
        [1] => #
        [3] => #
        [2] => #
    )
    [$] => $
    [%] => %
    [^] => ^
    [&] => &
    [*] => *
)
*/
Looking for a cloud-based catalog and CRM platform? Checkout http://rocware.com/

1 comment:

About Me

My photo
I code. I figured I should start a blog that keeps track of the many questions and answers that are asked and answered along the way. The name of my blog is "One Q, One A". The name describes the format. When searching for an answer to a problem, I typically have to visit more than one site to get enough information to solve the issue at hand. I always end up on stackoverflow.com, quora.com, random blogs, etc before the answer is obtained. In my blog, each post will consist of one question and one answer. All the noise encountered along the way will be omitted.