Re: Find keys in multidimensional array

From: Date: Thu, 25 Feb 2021 09:54:14 +0000
Subject: Re: Find keys in multidimensional array
References: 1 2  Groups: php.general 
Request: Send a blank email to php-general+get-327502@lists.php.net to get a copy of this message
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 <gordonisnz@gmail.com> 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. >

« previous php.general (#327502) next »