php - Categorise objects in a associative array grouped by a object property -


let me first explain problem. have simple value object poi. private properties , getters/setters left out sake of simplicity in example.

class poi implements jsonserializable {     public $latitude;     public $longitude;     public $category;      public function __construct($category, $lat, $long)     {         $this->category = $category;         $this->latitude = $lat;         $this->longitude = $long;     }      public function jsonserialize()     {         return array(             'lat' => $this->latitude,             'lng' => $this->longitude,         );     } } 

some dataproviders responsible returning array of poi's. i.e.

class poiprovider1 {     public function getpois()     {         return array(             new poi('airport', 10, 10),             new poi('airport', 10, 15),             new poi('restaurant', 30, 30),         )     } }  class poiprovider2 {     public function getpois()     {         return array(             new poi('hotel', 20, 20),             new poi('airport', 30, 30),         )     } } 

now want array structured follows, can json_encode()

array(     'airport' => array(         new poi('airport', 10, 10),         new poi('airport', 10, 15),         new poi('airport', 30, 30),     ),     'restaurant' => array(         new poi('restaurant', 30, 30),     ),     'hotel' => array(         new poi('hotel', 20, 20),     ) ); 

which after json_encode end in following structure:

{     "airport":[         {"lat":10,"lng":10},         {"lat":10,"lng":15},         {"lat":30,"lng":30}     ],     "restaurant":[         {"lat":30,"lng":30}     ],     "hotel":[         {"lat":20,"lng":20}     ] } 

i can create such structure using array_merge , array copying, this:

$provider1 = new poiprovider1(); $provider2 = new poiprovider2(); $pois = array_merge($provider1->getpois(), $provider2->getpois()); $poisnew = array(); foreach ($pois $poi) {     $poisnew[$poi->category][] = $poi; } 

obviously memory consuming , slow when dealing lots of poi's. there must nicer , faster way (i.e. using iterators), i'm not sure how approach this. give me pointers how proceed?

for speeding things eliminate post processing.

elimination of post processing:

you can use global or class static container pois auto indexes , stores them during construction this:

class poi implements jsonserializable {  public static $json;    // our new hero.  public $latitude; public $longitude; public $category;  public function __construct($category, $lat, $long){     $this->category = $category;     $this->latitude = $lat;     $this->longitude = $long;     array_push(self::$json[$category], $this); // trick... }  public function jsonserialize() {     return array(         'lat' => $this->latitude,         'lng' => $this->longitude,     ); } } poi::$json = array(); 

now @ each poi creation, poi instances stored poi::$json in form need.

generating poi's:

if not need process poi's, simplify providers also:

class poiprovider1 {  public function getpois(){      // no need return if json.    new poi('airport', 10, 10);  // because each instance automagically     new poi('airport', 10, 15);  // added poi::$json    new poi('restaurant', 30, 30); } } 

but if else on poi instances not use code above...

encoding:

since $json associated array can required output effect using

json_encode((object)poi::$json); 

the drawback poi's stick in memory , survive gc because reachable via poi::$json. after json_encode set

poi::$json  = null; 

i hope helps.


Comments