I'm visualizing my stored data in an histogram similar to this one:
However, I'm sure that my code smells a lot! So I'd like to have your opinion on how to make it better.
Here's my current code:
$listings = array(
array('Price' => 10),
array('Price' => 10),
array('Price' => 11)
); // so on and so forth, this data is pulled from the database.
// flattening the array so I remove the "Price" key
// the array takes the form of array(10,10,11,...)
foreach($listings as $listing) {
$flattenedListings[] = $listing['Price'];
}
$widths = range(0, 100, 10); // creates array of the form: array(0, 10, 20, 30, 40, ...)
$bins = array();
$isLast = count($widths);
foreach($widths as $key => $value) {
if($key < $isLast - 1) {
$bins[] = array('min' => $value, 'max' => $widths[$key+1]);
}
}
// creates array of the form:
// $bins = array(
// array('min'=>0, 'max' => 10),
// array('min'=>10,'max' => 20),
// array('min'=>30, 'max'=>40)
// );
$histogram = array();
foreach($bins as $bin) {
$histogram[$bin['min']."-".$bin['max']] = array_filter($flattenedListings, function($element) use ($bin) {
if( ($element > $bin['min']) && ($element <= $bin['max']) ) {
return true;
}
return false;
});
}
// Last one is a bit complicated, but basically what it does is that it creates an array of ranges as keys, so it generates this:
// array('0-10' => array(1, 2, 3, 4, 5, 6),
// '10-20' => array(11, 19, 12),
// '20-30' => array(),
// );
// Or in other words: foreach range in the histogram, php creates an array containing values within the allowed limits.
foreach($histogram as $key => $val) {
$flotHistogram[$key] = (is_array($val)) ? ( (count($val)) ? count($val) : 0 ) : 0;
}
// And finally it just counts them, and returns a new array.
As you can see in my code, I'm making an excessive use of foreach loops to basically doing a "simple task"
Basically what I have is a list of items along with their prices, and I want to count how many items belong to each range, my ranges are 10 numbers apart. (0 - 10, 10 - 20, 20 - 30, etc...)
Ideally the output should tell me how many items there are in a given category, like 3 items in the range of $10 - $20, 2 items in the range of $20 - $30 and 1 item in the range of $30 - $40, etc... In the following format:
array('0-10' => 0, '10-20' => 3, '20-30' => 2, '30-40' => 1);
Given the following input:
array(
array('Price' => 11),
array('Price' => 12),
array('Price' => 20),
array('Price' => 25),
array('Price' => 20.1),
array('Price' => 33.5)
);
Hope my question is clear enough.
Additional info:
I'm pulling my prices from a MySQL database using PDO option PDO::FETCH_ASSOC
any help skipping the flattening of the array will be greatly appreciated (instead of fetching an array of arrays, just fetch the numbers in a 1 dimensional array).