Skip to content

Instantly share code, notes, and snippets.

@Jeff-Russ
Last active February 18, 2017 05:09
Show Gist options
  • Save Jeff-Russ/bc96cd2e36c5ddd3dbb09c8bde8d7cb3 to your computer and use it in GitHub Desktop.
Save Jeff-Russ/bc96cd2e36c5ddd3dbb09c8bde8d7cb3 to your computer and use it in GitHub Desktop.
PHP Recursive Array Search
<?php
function recursive_search($val, $arr, $mode=1, $strict=true)
{
$depth = ($depth=(int)$mode) ? $depth : 0;
if (strpos($mode, 'all')!==false) {
$r = function ($val, $a, $d, $s, $l=0, &$path=[], &$keys=[], &$i=0) use (&$r) {
foreach($a as $k=>$v) {
$path[] = $k;
if (!$s && $v==$val || $v===$val) $keys[$i++] = $path;
elseif ($l<$d && (is_array($v) /*|| method_exists($v,'getIterator')*/))
$r($val, $v ,$d, $s, $l, $path, $keys, $i);
array_pop($path);
}
if ($l!==0) return $keys ? $keys : false;
return array_values( $keys );
};
} else {
$r = function ($val, $a, $d, $s, $l=0, $keys=array()) use (&$r) {
foreach($a as $k=>$v) {
if (!$s && $v==$val || $v===$val) { $keys[]=$k; return $keys; }
elseif ($l<$d && (is_array($v) /*|| method_exists($v,'getIterator')*/)) {
$keys[]=$k;
if ($keys=$r($val, $v ,$d, $s, $l+1, $keys)) return $keys;
}
}
return false;
};
}
return $r($val, $arr, $depth, $strict);
}
$arr = array(
0=>array(1=>array(2=>'depth2') ),
'1.4' => 0,
'depth1'=>array('depth1'),
'arr1'=>array(
'arr2'=>array(
'arr3'=>array('findme'),
),
),
'findme1'=>array('findme'),
);
print_vals(recursive_search('depth1', $arr)); # ['depth1', 0]
print_vals(recursive_search('depth1', $arr, 0)); # [ ]
print_vals(recursive_search('depth1', $arr, 0, false));# ['1.4'] beware! non-strict
print_vals(recursive_search('depth2', $arr)); # [ ] default depth is 1
print_vals(recursive_search('depth2', $arr, 2)); # [0,1,2] depth now 2
print_vals(recursive_search('findme', $arr, 3)); # ['arr1','arr2','arr3',0]
// note that the value 'findme' occured twice but we only caught one
print_vals(recursive_search('findme', $arr, '3 all')); # ['arr1','arr2','arr3',0]
/* a third argument containing 'all' and optionally starting with an int
* will return an array of recursive_search values:
[
['arr1', 'arr2', 'arr3', 0],
['findme1', 0],
]
*/
////////////////////////////////////////////////////////////////////////////////
// just to display demo:
function print_vals($arr) {
if (!$arr) { echo "[ ]\n"; return; }
foreach ($arr as $v) { if (is_array($v)) {$run_sub=true; break;} }
if (isset($run_sub)) {
$subs = function ($arr) {
echo "[\n";
foreach ($arr as $sub) {
if (!$sub) { echo "[ ]\n"; return; }
$s = is_int($sub[0]) ? "\t[${sub[0]}": "\t['${sub[0]}'"; unset($sub[0]);
foreach($sub as$v) $s = is_int($v) ? "$s, $v" : "$s, '$v'";
echo "$s],\n";
}
echo "]\n";
};
return $subs($arr);
}
$s = is_int($arr[0]) ? "[${arr[0]}": "['${arr[0]}'"; unset($arr[0]);
foreach($arr as$v) $s = is_int($v) ? "$s,$v" : "$s,'$v'";
echo "$s]\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment