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
Post a Comment