PHP - 在多维数组中查找以前的值
I have this array:
$test = array( "a" => "b",
"c" => array("foo" => "bar",
"3" => "4",
),
"e" => "f",);
I want to create a function that finds the previous value in this array, given a certain value, for example find("bar", $test);
should return "b".
This is what I got:
function find($needle, $array, $parent = NULL)
{
//moves the pointer until it reaches the desired value
while (current($array) != $needle){
//if current value is an array, apply this function recursively
if (is_array(current($array))){
$subarray = current($array);
//passes the previous parent array
find($needle, $subarray, prev($array));
}
//once it reaches the end of the array, end the execution
if(next($array) == FALSE){
return;
}
}
//once the pointer points to $needle, run find_prev()
find_prev(prev($array), $parent);
}
function find_prev($prev, $parent = NULL)
{
// in case there is no previous value in array and there is a superior level
if (!$prev && $parent) {
find_prev($parent);
return;
}
// in case previous value is an array
// find last value of that array
if (is_array($prev) && $prev){
find_prev(end($prev), $parent));
return;
} else {
$GLOBALS['pre'] = $prev;
}
}
For pedagogical reasons and since I have devoted some time to this function, it would be great if you could provide any hints about why this isn't working rather than any other simpler solution that you might have.
You have an infinite loop. Your algorithm is a bit complicated for what you want to do. Maybe you should just keep the previous value in a variable and return it when you find the $needle
. Here is the corresponding code. I tried to not modify your code as much as I could:
function find($needle, $array, $lastValue = NULL)
{
$previousValue = null;
//moves the pointer until it reaches the desired value
while (current($array) != FALSE) {
$value = current($array);
//if current value is an array, apply this function recursively
if (is_array($value)) {
$subarray = $value;
//passes the previous value as the last value for the embedded array
$value = find($needle, $subarray, $previousValue);
if ($value !== NULL) {
return $value;
}
} else if ($value === $needle) {
//returns the previous value of the current array
if ($previousValue !== NULL) {
return $previousValue;
//returns the last checked value of the parent array
} else if ($lastValue !== NULL) {
return $lastValue;
} else {
return;
}
} else {
$previousValue = $value;
}
next($array);
}
}
$test = array(
"a" => "b",
"c" => array(
"foo" => "bar",
"3" => "4"
),
"e" => "f"
);
$result = find("bar", $test);
if ($result === null) {
print('no previous value');
} else {
$GLOBALS['pre'] = $result;
print($GLOBALS['pre']);
}
You may try TDD to code this kind of algorithm. It could help you.
The function find()
calls itself recursively for sub-arrays but it doesn't check if the inner call found something or not and keep searching. This is why the first call to find_prev()
runs with $test['b']
as its first parameter (prev()
of the last element in $test
). You expect it to run with $test['a']
.