views:

193

answers:

2

I'm having trouble trying to figure out how to achieve this programming challenge in my Zend Framework application:

I need to create an array that looks like this:

$array = array(
    0 => stdClass()->monthName
                   ->monthResources = array()
    1 => stdClass()->monthName
                   ->monthResources = array()
);

This is the original array I have to work with:

$resources = array(
    0 => Resource_Model()->date (instance of Zend_Date)
    1 => Resource_Model()->date
    2 => Resource_Model()->date
    //etc...
);

The original array ($resources) is already sorted by date (descending) so I need to create an array where the resources are grouped by month. I only want the months that have resources, so if the resources skip a month, there shouldn't be a stdClass object for that month in the final array.

I also want this to process quickly, so any advice on optimizing the code (and still being readable) would be great. How can I achieve this?

A: 

Maybe this helps (pseudo-code)

$finalArray = new array();
$tempStdClass = null;

foreach ($resObj in $resources)
{
    if ($tempStdClass == null)
     $tempStdClass = new StdClass($resObj->date);

    if (tempStdClass->monthName != $resObj->date)
    {
     array_push($finalArray, $tempStdClass);
     $tempStdClass = new StdClass($resObj->date);
    }

 array_push($tempStdClass->monthResources, $resObj);    
}
Bobby
+1  A: 

My offering. No guarantees on its speed however it is O(n) and should in theory be faster than your method. This may not be true in any or all cases. However if you want something optimized you should have used a profiler to ensure that this is the function that is causing the speed problems rather than trying to make sections of code fast when they only account for .001% of the execution time. (In which case the maximum gain from optimizing the function would be .001%)

$resources = $this->fetchAll();
$sortedresources = array();
foreach ($resources as $resource) {

    $monthName = $resource->getDate()->get(Zend_Date::MONTH_NAME);

    if ( !isset($sortedresources[$monthName]) ){
        //setup new data for this month name
        $month = new stdClass();
        $month->name = $monthName;
        $month->monthResources = array();
        $sortedresources[$monthName] = $month;
    }

    $sortedresources[$monthName]->monthResources[] = $resource;
}
//return the values of the array, disregarding the keys
//so turn array('feb' => 'obj') to array(0 => 'obj)
return array_values($sortedresources);
Yacoby
Yes. Fixed [15chars]
Yacoby
I only mentioned that I wanted it optimized because the only way I could think of doing it would involve iterating through the array multiple times (which I knew probably wasn't necessary).
Andrew