Reputation: 1111
I would like te perform a calculation on the following array
$array = [
"calculation" => [
"add" => [
"ceil" => [
"multiply" => [
9.95,
"90%"
]
],
0.95
]
]
];
eventually the calculation would traverse into:
1. add(ceil(multiply(9.95, 90%)), 0.95)
2. ceil(multiply(9.95, 90%)) + 0.95
3. ceil(8.955) + 0.95
4. 9 + 0.95
5. 9.95
I've tried recursively looping through the array using array_walk_recursive and custom functions which basically to the same.
but the problem is that the add
cannot calculate the ceil
before it has calculated the multiply
.
So how can i recusively in reversed order calculate all the parts of the array?
I'm slowly loosing my mind over this and starting to question if it's even possible.
All ideas are greatly appreciated
Upvotes: 0
Views: 67
Reputation: 2595
Another option, that verify the indexes of the array are valid functions and allows add
and multiple
with more than 2 values.
function multiply(...$a)
{
return array_product($a);
}
function add(...$a)
{
return array_sum($a);
}
function applyCalculation(array $data)
{
$firstKey = array_keys($data)[0];
$arguments = [];
foreach ($data[$firstKey] as $name => $value) {
// if argument is array with existing function, we pass it recursively
if (function_exists($name) && is_array($value)) {
$result = applyCalculation([$name => $value]);
$result = is_array($result) ? $result : [$result];
$arguments = array_merge($arguments, $result);
} elseif (!is_array($value)) {
// if not array, just append to arguments
$value = strpos($value, '%') !== false ? str_replace('%','',$value) / 100 : $value;
$arguments[] = $value;
} elseif (is_array($value)) {
// error here, the index is not a valid function
}
}
return $firstKey(...$arguments);
}
echo applyCalculation($array['calculation']);
So it will work for your example:
$data = [
"calculation" => [
"add" => [
"ceil" => [
"multiply" => [
9.95,
'90%',
]
],
0.95
]
]
];
// will give you 9.95
But it also works for more complex cases::
$array = [
"calculation" => [
"add" => [
"ceil" => [
"add" => [
"multiply" => [
9.95,
'90%'
],
"add" => [
1,
3
],
]
],
0.95,
3
]
]
];
// will give you 16.95
Upvotes: 2
Reputation: 15131
Assuming that you have this structure, you may use this code. If you need more than 2 values to be "added" or "multiplied" you may need to use some splat operator or change the logic a little bit:
<?php
$array = [
"calculation" => [
"add" => [
"ceil" => [
"multiply" => [
9.95,
"90%"
]
],
0.95
]
]
];
function add($a, $b) {
return $a + $b;
}
function multiply($a, $b) {
return $a * $b;
}
function calculation($arr, $operation = null) {
$elements = [];
foreach($arr as $k => $value) {
if (is_numeric($k)) {
// change % with valid numeric value
if(strpos($value, '%')) {
$value = str_replace('%','',$value) / 100;
}
//if there are no operations, append to array to evaluate under the operation
$elements[] = $value;
} else {
//if there are operations, call the function recursively
$elements[] = calculation($value, $k);
}
}
if ($operation !== null) {
return call_user_func_array($operation, $elements);
}
return $elements[0];
}
echo calculation($array['calculation']);
Upvotes: 1