我遇到一个问题,我试图获取一个对象的所有后代,并仅保留具有特定属性的对象。
我有这些关系:
public function getChildren()
{
return $this->hasMany(self::class, 'parent_id', 'id');
}
public function allChildren()
{
return $this->getChildren()->with('allChildren');
}
例如,我得到这种类型的数组:
$array = [
0 => ['name' => 'aaa', 'type' => 0, 'parent' => null, 'children' => [
1 => ['name' => 'bbb', 'type' => 1, 'parent' => null, 'children' => []],
2 => ['name' => 'ccc', 'type' => 0, 'parent' => null, 'children' => [
3 => ['name' => 'ddd', 'type' => 1, 'parent' => 2, 'children' => []]
]]
]],
4 => ['name' => 'eee', 'type' => 0, 'parent' => null, 'children' => []]
];
对于此示例,我想删除所有type 1
的对象,并获得一个仅包含这些对象的干净数组。
我不太了解为什么可以获取一个对象的所有后代,但无法通过条件。
谢谢。
答案 0 :(得分:1)
仅收集解决方案就是这样(将自定义宏放在应用程序的服务提供商中):
Collection::macro('whereDeep', function ($column, $operator, $value, $nested) {
return $this->where($column, $operator, $value)->map(function ($x) use ($column, $operator, $value, $nested) {
return $x->put($nested, $x->get($nested)->whereDeep($column, $operator, $value, $nested));
});
});
然后在需要的地方致电:
$yourArray->whereDeep('type', '!=', 1, 'children');
在您的示例中,宏的工作方式如下:
type != 1
type => 0
,所以外部数组将保持不变)children
属性,并从本指令的第一点开始,对该子数组应用相同的过滤。children
属性。无论如何,您应该尝试深入探究为什么关系过滤不起作用。如果正确优化,该解决方案将更加有效。
答案 1 :(得分:0)
我找到了一个很好的解决方案,其中不需要所有此类递归或任何这些关系调用,因此可以与我分享:
使用:"gazsp/baum"
// get your object with roots method
$contents = Content::roots()->get();
// and simply run through the object and get whatever you need
// thanks to getDescendantsAndSelf method
$myArray = [];
foreach($contents as $content) {
$myArray[] = $content->getDescendantsAndSelf()->where('type', '!=', 1)->toHierarchy();
}
return $myArray;
对我来说,此方法与上述其他方法相同。