I have an associative array with 15 different companies and their stock prices, formatted as shown below:
$CloseStockPrice ('Business'=>50.5. 'Business two'=>100.5, .....)
I have found the average stock price:
$Average = (array_sum($CloseStockPrice)/count($CloseStockPrice));
The average ends up being 161.
But I now need to find the closest number (absolute terms) to that average value (161) within the associative array. I need to display the business and the stock value.
My most recent attempt:
function computeClosest(array $CloseStockPrice) { $closest = 161; for ($i = 161; $i < count($CloseStockPrice) ; $i++) { if ($closest === 161) { $closest = $CloseStockPrice[$i]; } else if ($CloseStockPrice[$i] > 161 && $CloseStockPrice[$i] <= abs($closest)) { $closest = $CloseStockPrice[$i]; } else if ($CloseStockPrice[$i] < 161 && -$CloseStockPrice[$i] < abs($closest)) { $closest = $CloseStockPrice[$i]; return $closest; } } }
Any suggestions?
Advertisement
Answer
While you loop through your array of business entries, cache the businesses with prices with the smallest absolute difference involving the average value.
While you might expect a single value in many cases, the fact that multiple qualifying businesses is possible means that you must keep an array of qualifying businesses for most accurate results.
A linear (single loop) process (O(n)
) will outperform a sort algorithm (O(n log n)
).
https://stackoverflow.com/q/56506410/2943403
Code: (Demo)
$closeStockPrice = [ 'A' => 50, 'B' => 155, 'C' => 75, 'D' => 245, 'E' => 300, 'F' => 100, 'G' => 153, ]; $average = array_sum($closeStockPrice) / count($closeStockPrice); $bestDistances = []; foreach ($closeStockPrice as $business => $price) { $distance = abs($average - $price); $current = current($bestDistances); if (!$bestDistances || $current > $distance) { $bestDistances = [$business => $distance]; // new best distance } elseif ($current === $distance) { $bestDistances[$business] = $distance; // push business with same distance } } var_export([ 'average' => $average, 'bestDistances' => $bestDistances, 'bestBusinessPrices' => array_intersect_key($closeStockPrice, $bestDistances) ]);
Output:
array ( 'average' => 154, 'bestDistances' => array ( 'B' => 1, 'G' => 1, ), 'bestBusinessPrices' => array ( 'B' => 155, 'G' => 153, ), )