首先让我解释一下我的问题。
我有一个简单的值对象Poi
。在此示例中,为了简单起见,省略了私有属性和getter / setter。
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,
);
}
}
一些数据提供者负责返回一组Poi。即。
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),
)
}
}
现在我想要一个数组结构的跟随,我可以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),
)
);
在json_encode结束之后会出现以下结构:
{
"airport":[
{"lat":10,"lng":10},
{"lat":10,"lng":15},
{"lat":30,"lng":30}
],
"restaurant":[
{"lat":30,"lng":30}
],
"hotel":[
{"lat":20,"lng":20}
]
}
我可以使用array_merge
和一些数组复制创建这样的结构,如下所示:
$provider1 = new PoiProvider1();
$provider2 = new PoiProvider2();
$pois = array_merge($provider1->getPois(), $provider2->getPois());
$poisNew = array();
foreach ($pois as $poi)
{
$poisNew[$poi->category][] = $poi;
}
显然,当处理大量的poi时,这会消耗内存并且速度很慢。 必须有一些更好更快的方法(即使用迭代器),但我不知道如何处理这个问题。谁能给我一些指示如何继续?
答案 0 :(得分:0)
为了加快速度,消除后期处理。
消除后处理:
您可以使用另一个全局或类静态容器作为pois,在构造期间自动索引和存储它们,如下所示:
class Poi implements JsonSerializable {
public static $json; // this is 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); // this does the trick...
}
public function jsonSerialize()
{
return array(
'lat' => $this->latitude,
'lng' => $this->longitude,
);
}
}
Poi::$json = array();
现在每次poi创建时,poi实例都以你需要的形式存储到Poi :: $ json中。
生成兴趣点
如果您不需要处理poi ,这也会简化您的提供商:
class PoiProvider1 {
public function getPois(){ // no need to return if they are just for json.
new Poi('airport', 10, 10); // because each instance will be autoMagically
new Poi('airport', 10, 15); // added to Poi::$json
new Poi('restaurant', 30, 30);
}
}
但如果你在poi实例上做了其他事情,请不要使用上面的代码......
<强>编码强>
由于$ json是一个关联数组,因此您可以使用
获得所需的输出效果json_encode((object)Poi::$json);
缺点是poi会坚持内存并在gc中生存,因为它们可以通过Poi :: $ json访问。所以在你json_encode设置
之后Poi::$json = null;
我希望这会有所帮助。