如何在 Laravel 集合中创建数组

How to create an array inside a Laravel collection

我正在使用 Laravel 7。 我需要检索所有有许多团队参与的项目。

这是我在控制器方法中编写的代码:

    public function index()
    {
        $projects = Project::select('projects.id as id', 'projects.name as name', 'teams.name as team_name')
            ->leftJoin('tasks', 'projects.id', '=', 'tasks.project_id')
            ->join('task_user', 'tasks.id', '=', 'task_user.task_id')
            ->join('users', 'task_user.user_id', '=', 'users.id')
            ->join('teams', 'users.team_id', '=', 'teams.id')
            ->orderBy('projects.id')
            ->distinct()
            ->get();

        foreach ($projects as $key => $value) {
            $projects_length = $projects->where('id', $value['id'])->count();
            if($projects_length === 1) {
                unset($projects[$key]);
            }
        }

        $projects = $projects->values();

        return $projects;
}

我return为$projects的数据格式如下:

[
    {
        "id": 2,
        "name": "Creating new app with Symfony",
        "team_name": "Warriors"
    },
    {
        "id": 2,
        "name": "Creating new app with Symfony",
        "team_name": "Guardians"
    },
    {
        "id": 3,
        "name": "Creating new app with Vue.js",
        "team_name": "Warriors"
    },
    {
        "id": 3,
        "name": "Creating new app with Vue.js",
        "team_name": "Reds"
    }
]

正如您想象的那样,使用类似的响应数据格式很困难。 我想将 team_name 数据封装到一个数组中,如下所示:

[
    {
        "id": 2,
        "name": "Creating new app with Symfony",
        "team_name": 
            [
                "Warriors",
                "Guardians"
            ]
    },
    {
        "id": 3,
        "name": "Creating new app with Vue.js",
        "team_name": 
            [
                "Warriors",
                "Reds"
            ]
    }
]

可以帮忙吗?

collect([
    [
        "id"=> 2,
        "name"=> "Creating new app with Symfony",
        "team_name"=> "Warriors"
    ],
    [
        "id"=> 2,
        "name"=> "Creating new app with Symfony",
        "team_name"=> "Guardians"
    ],
    [
        "id"=> 3,
        "name"=> "Creating new app with Vue.js",
        "team_name"=> "Warriors"
    ],
    [
        "id"=> 3,
        "name"=> "Creating new app with Vue.js",
        "team_name"=> "Reds"
    ]
])->groupBy('id')->map(function($data, $id) {
  return [
    'id' => $id,
    'name' => $data[0]['name'],
    'team_nameS' => $data->pluck('team_name')->toArray()
  ];
})->values()->toArray()

一种方法。也许您可以考虑使用 eloquent 方法 withwhereHas 等来解决查询中的大部分问题。

输出

=> [
     [
       "id" => 2,
       "name" => "Creating new app with Symfony",
       "team_nameS" => [
         "Warriors",
         "Guardians",
       ],
     ],
     [
       "id" => 3,
       "name" => "Creating new app with Vue.js",
       "team_nameS" => [
         "Warriors",
         "Reds",
       ],
     ],
   ]

您可以尝试在 eloquent 中使用 GROUP_CONCAT 和分组依据。我的查询浏览器上没有 运行 它,但您可以验证一次并共享日志,以检查是否有进一步的错误。

    $projects = Project::select('projects.id as id')
        ->leftJoin('tasks', 'projects.id', '=', 'tasks.project_id')
        ->join('task_user', 'tasks.id', '=', 'task_user.task_id')
        ->join('users', 'task_user.user_id', '=', 'users.id')
        ->join('teams', 'users.team_id', '=', 'teams.id')
        ->selectRaw('GROUP_CONCAT(projects.name) as name', 'GROUP_CONCAT(teams.name) as team_name')
        ->groupBy('projects.id')
        ->orderBy('projects.id')
        ->get();