Re: Find keys in multidimensional array

[email protected] (Rene Veerman)
Newsgroups php.general
Message-ID <CACMzB5fxZh2RERqwkYtBx8JpnFnnmE1DXud4dAByL-zVWvRW5w@mail.gmail.com>
i have built some functions which do this sort of thing.
i'll share them with you..

function walkArray (&$a, $keyCallback=null, $valueCallback=null,
$callKeyForValues=false, $callbackParams=null, $k='', $level=0, $path='') {
// usage : walkArray ($someRecursiveArray, 'walkArray_printKey',
'walkArray_printValue');
// can handle recursive arrays. a nested array is a recursive array.
// is faster, especially on large arrays, than RecuriveArrayIterator, see
speed testing comment at
http://php.net/manual/en/class.recursiveiteratoriterator.php
// provides detailed information to callbacks on where in the data we are,
something that array_walk_recursive just doesnt do.
// passes data around as pointers, not copies of data.
    if (!is_array($a)) {
        return badResult (E_USER_ERROR, array (
            'msg' => 'walkArray() was called but $a parameter passed is not
an array.'
        ));
    } else {
        foreach ($a as $k=>&$v) {
            $cd = array ( // callback data
                'type' => 'key',
                'path' => $path,
                'level' => $level,
                'k' => &$k,
                'v' => &$v,
                'params' => &$callbackParams
            );
            if (!is_null($keyCallback) && ($callKeyForValues ||
is_array($v))) call_user_func ($keyCallback, $cd);
            if (is_array ($v)) {
                walkArray ($a[$k], $keyCallback, $valueCallback,
$callKeyForValues, $callbackParams, $k, $level+1, $path.'/'.$k);
            } else {
                $cd['type'] = 'value';
                if (!is_null($valueCallback)) call_user_func
($valueCallback, $cd);
            }
        }
    }
    $r = true;
    return goodResult($r);
}

function walkArray_printKey ($cd) {
    echo '<div
style="background:blue;color:yellow;border-radius:5px;padding:2px;margin-top:5px;">'.PHP_EOL;
    $indent = 20 * $cd['level'];
    echo '<div style="padding-left:'.$indent.'px">'.PHP_EOL;
    echo 'key : '.$cd['k'].'<br/>'.PHP_EOL;
    echo 'path : '.$cd['path'].'<br/>'.PHP_EOL;
    echo '</div>'.PHP_EOL;
    echo '</div>'.PHP_EOL;
}

function walkArray_printValue ($cd) {
    echo '<pre
style="background:green;color:white;border-radius:5px;padding:2px;margin-top:2px;">'.PHP_EOL;
    $indent = 20 * $cd['level'];
    echo '<div style="padding-left:'.$indent.'px">'.PHP_EOL;
    echo 'key : '.$cd['k'].'<br/>'.PHP_EOL;
    echo 'path : '.$cd['path'].'<br/>'.PHP_EOL;
    echo 'value : '.$cd['v'].'<br/>'.PHP_EOL;
    echo '</div>'.PHP_EOL;
    echo '</pre>'.PHP_EOL;
}


function &chaseToPath (&$wm, $path, $create=false) {
    //var_dump ($create); die();
    //echo '$wm=<pre>'; var_dump ($wm);echo '</pre>'; //die();
    //$path = str_replace ('/', '/d/', $path);
    //$path .= '/d';
    $nodes = explode ('/', $path);
    foreach ($nodes as $idx=>$node) {
        if (is_numeric($node) && is_string($node)) {
            if (strpos($node,'.')===false) {
                $nodes[$idx] = (int)$node;
            } else {
                $nodes[$idx] = (float)$node;
            }
        }
    }
    $chase = &chase ($wm, $nodes, $create);

    //echo '$wm=<pre>'; var_dump ($wm);echo '</pre>'; die();
    /*
    $dbg = array (
        '$path' => $path,
        '$nodes' => $nodes,
        '$wm' => $wm,
        '$chase' => $chase
    );
    echo '$dbg=<pre style="background:red;color:yellow;">'; var_dump
($dbg); echo '</pre>';
    */
    //die();


    $false = false;
    if (good($chase)) {
        $arr = &result($chase);
        return $arr;
    } else return $false;
}


function &chase (&$arr, $indexes, $create=false) {
        if (false) {
        echo 'sitewide/functions.php --- $arr=<pre>'; var_dump ($arr); echo
'</pre>';
        echo 'sitewide/functions.php --- $indexes=<pre>'; var_dump
($indexes); echo '</pre>';
        echo 'sitewide/functions.php --- $create=<pre>'; var_dump
($create); echo '</pre>';
        }
$r = &$arr;
foreach ($indexes as $idx) {
            //echo 'sitewide/functions.php --- $idx=<pre>'; var_dump
($idx); var_dump (array_key_exists($idx,$r)); var_dump ($r); echo '</pre>';
            if (
                    is_array($r)
                    && (
                            $create===true
                            || array_key_exists($idx,$r)
                    )
            ) {
                    if ($create===true && !array_key_exists($idx,$r))
$r[$idx]=array();
                    //echo 'sitewide/functions.php --- $idx=<pre>';
var_dump ($idx); echo '</pre>';
                    $r = &$r[$idx];
            } else {
                /*
                    $err = array(
                    'msg' => 'Could not walk the full tree',
                    'vars' => array(
                            '$idx--error'=>$idx,
                            '$indexes'=>$indexes,
                            '$arr'=>$arr
                            )
                    );
                    badResult (E_USER_NOTICE, $err);
                    */
                    $ret = false; // BUG #2 squashed
                    return $ret;
            }
}

        //echo 'sitewide/functions.php --- $r=<pre>'; var_dump ($r); echo
'</pre>';
return goodResult($r);
}

function &chaseToReference (&$array, $path) {
if (!empty($path)) {
if (empty($array[$path[0]])) {
$err = array(
'msg' => 'Could not walk the full tree',
'$path' => $path,
'$array (possibly partially walked)' => $array
);
return badResult (E_USER_NOTICE, $err);
} else return chaseToReference($array[$path[0]], array_slice($path, 1));
} else {
return goodResult($array);
}
}

function good($r) {
return (
is_array($r)
&& array_key_exists('result',$r)
);
}

function &result(&$r) {
return $r['result'];
}

function &resultArray (&$r) {
  $r2 = array();
  foreach ($r as $k => $v) {
    $r2[$k] = result($v);
  }
  return $r2;
}


function &goodResult(&$r) {
$r2 = array (
'isMetaForFunc' => true,
'result' => &$r
);
return $r2;
}

On Thu, Feb 25, 2021 at 7:59 AM <[email protected]> wrote:

> Hello. I have a multidimensional array.
>
> Some 'routes' only go 2-3 key/values down, While other options have
> 6-10 keys deep (Ive not planned this as yet - just started)..
>
> In the below array (just random words) I'm 'at' the 'Ginger' option
> now. I am wondering if there was a quick way of searching the array
> for 'Ginger' and finding the path "up"  the array to get the key 2
> levels up.
>
> So for this example i'll want to go 'up' 2 levels to get 'crackers'
>
> (each unique key, will have a TITLE value, and a number of OPTIONS -
> 2-6 options each)
>
> Is there a quick way of doing this ?
>
> EXAMPLE array:-
>
> (
>     [top] => Array
>         (
>             [CRUSH] => Array
>                 (
>                     [TITLE] => Crush
>                     [OPTION1] => Array
>                         (
>                             [cheese] => Array
>                                 (
>                                     [TITLE] => Cheese option
>                                 )
>
>                         )
>
>                     [OPTION2] => Array
>                         (
>                             [crackers] => Array
>                                 (
>                                     [TITLE] => crackers
>                                     [OPTION1] => Array
>                                         (
>                                             [NAME] => crackers option 1
>                                             [Ginger] => Array
>                                                 (
>                                                     [TITLE] => Ginger
> title1
>                                                     [TITLE2] => Ginger
> title2
>                                                 )
>
>                                         )
>
>                                     [OPTION2] => crackers option 2
>                                 )
>
>                         )
>
>                 )
>
>         )
>
> )
>
>
>
>
>
> --
>
> Gordon.
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.