Re: Find keys in multidimensional array

[email protected] (Glash Gnome)
Newsgroups php.general
Message-ID <CADeZBNaKqxkrTo0UzN8iAJJRrwHmTycvsiV2j8g+m4cLS9y4SQ@mail.gmail.com>
Hello,

I would like to suggest another solution...

/**
 * Convert an array into a DOMDocument and use the power of DOMXPath
 */
function testRecreational () {

    $array = 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'
                    )
                )
            )
        )
    );
    $dom = new \DomDocument();
    $walker = function($value, $key, $node) use(&$walker, &$dom){
        if (is_string($value)) {
            $elt = $dom->createElement($key, $value);
            $node->appendChild($elt);
        } else if(is_array($value)) {
            $elt = $dom->createElement($key);
            $node->appendChild($elt);
            array_walk($value, $walker, $elt);
        }
    };
    array_walk($array, $walker, $dom);
    $xpath = new \DOMXPath($dom);
    $nodes = $xpath->query("//crackers");// Or
"//TITLE[contains(text(), 'crackers')]/.."
    for($node=$nodes[0]; $node; $node=$node->parentNode) {
        echo $node->nodeName, PHP_EOL;// It's your turn ;-)
    }

}

Have fun

Kind regards,
Serge


Le jeu. 25 févr. 2021 à 10:54, Rene Veerman <
[email protected]> a écrit :

> 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.