I would like to solve the following problem while following the principles of functional programming. I have an array with "date To" ranges with these values: [30,60,90,120,360] and this array represents days intervals:
Index : interval
- - - - - - - - -
0 : 0-30
1 : 31-60
2: 61-90
4 : 91–360
5 : 361 – infinity
Now I have a value of x , let's say 75 days. Using functional programming, how do I find out (according to the days intervals defined in the array) that this value belongs to an interval with index 2?
I solved this algorithm in function with loop, but I know, that I should use recursive call instead. I don't know how.
Here is my code:
function indexByDateRange(array $intervalRange, int $days) {
foreach ($intervalRange as $i=>$value) {
if ($days <= $value) {
return $i;
}
}
return count($intervalRange);
}
$index = indexByDateRange(array(30,60,90,120,360), 73); // 73 is between 61 and 90 , so should return index = 2
$index = indexByDateRange(array(30,60,90,120,360), 4; // 4 is smaller then 30 , so should return index = 0
Any suggestion how to rewrite the indexByDateRange function so it will comply with Functional Programming principles?
CodePudding user response:
Define a function that takes an array and a callback function. This will use a loop like the one that you wrote to find the first array element that satisfies the function. Then you can call that in your functional programming style.
function array_search_callback($callback, $array) {
foreach ($array as $i => $el) {
if (($callback)($el)) {
return $i;
}
}
return count($array);
}
$intervalRange = [30,60,90,120,360];
$days = 73;
$index = array_search_callback(function($value) use ($days) {
return $days <= $value;
}, $intervalRange);
CodePudding user response:
just quick sample how you can do it in more functional way:
function indexByDateRange(array $intervalRange, int $days) {
return array_key_first(array_filter(
$intervalRange,
function($v) use ($days) {
return $days <= $v;
})) ?? count($intervalRange);
}
CodePudding user response:
I don't see any compelling reason to use recursion for such a basic, linear value searching function.
Simply find the key of the element which is the first to meet or exceed the target value. A continual break
or return
will ensure best performance.
Code: (Demo)
function greatestIndexWhereValueLessThan($haystack, $needle) {
foreach ($haystack as $key => $value) {
if ($value >= $needle) {
break;
}
}
return $key ?? null;
}
echo greatestIndexWhereValueLessThan([30, 60, 90, 120, 360], 73); // 2
echo "\n";
echo greatestIndexWhereValueLessThan([30, 60, 90, 120, 360], 4); // 0