Search code examples
phplaravellaravel-collection

Laravel Collection ordered by day of the week M-F


I have a Laravel collection grouped by day of the week but they are in the wrong order. I need them ordered by day of the week starting with Monday.

My Controller:

public function getWeeklySchedule()
    {
        $testSchedule = VolunteerSchedule::all();

        $result = $testSchedule->groupBy(['assignment', function ($item) {
            return $item['scheduled_days'];
        }]);

        return $result;
    }

The result looks like this:

  "Wednesday": {
    "kitchen": [
      {
        "id": 1,
        "full_name": "Hipolito Carroll",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ],
    "driver": [
      {
        "id": 3,
        "full_name": "Prof. Conor Grimes I",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ],
    "bagger": [
      {
        "id": 4,
        "full_name": "Martine Kemmer Sr.",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      },
      {
        "id": 10,
        "full_name": "Marcellus Walker",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ]
  },
  "Thursday": {
    "kitchen": [
      {
        "id": 1,
        "full_name": "Hipolito Carroll",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      },
      {
        "id": 7,
        "full_name": "Leonardo Schaefer V",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ],
    "driver": [
      {
        "id": 3,
        "full_name": "Prof. Conor Grimes I",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      },
      {
        "id": 5,
        "full_name": "Prof. Pablo Corwin",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ],
    "bagger": [
      {
        "id": 6,
        "full_name": "Samantha Feil",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      },
      {
        "id": 10,
        "full_name": "Marcellus Walker",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ]
  },
  "Friday": {
    "kitchen": [
      {
        "id": 1,
        "full_name": "Hipolito Carroll",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ],
    "driver": [
      {
        "id": 3,
        "full_name": "Prof. Conor Grimes I",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      },
      {
        "id": 9,
        "full_name": "Miss Eleonore Kutch IV",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ],
    "bagger": [
      {
        "id": 4,
        "full_name": "Martine Kemmer Sr.",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      },
      {
        "id": 10,
        "full_name": "Marcellus Walker",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ]
  },
  "Tuesday": {
    "kitchen": [
      {
        "id": 2,
        "full_name": "Miss Lessie Torphy",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      },
      {
        "id": 7,
        "full_name": "Leonardo Schaefer V",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ],
    "bagger": [
      {
        "id": 10,
        "full_name": "Marcellus Walker",
        "created_at": "2021-11-05T17:33:52.000000Z",
        "updated_at": "2021-11-05T17:33:52.000000Z"
      }
    ]
  },
  "Saturday": {...

Some fields have been removed for brevity. The days of the week are stored as a serialized array in the database. What is the best way to accomplish this?


Solution

  • Just define a custom sort function that uses a map for the days of the week:

    $days = ["Monday" => 1, "Tuesday" => 2, "Wednesday" => 3, "Thursday" => 4, "Friday" => 5, "Saturday" => 6, "Sunday" => 7];
    $collection = collect(["Friday" => [], "Wednesday" => [], "Tuesday" => []]);
    
    $collection->sortBy(fn($val, $key) => $days[$key]);
    
    dump($collection);
    

    Output:

    => Illuminate\Support\Collection {#4977
         all: [
           "Tuesday" => [],
           "Wednesday" => [],
           "Friday" => [],
         ],
       }
    

    So your code becomes:

    public function getWeeklySchedule(): Collection
    {
        $days = ["Monday" => 1, "Tuesday" => 2, "Wednesday" => 3, "Thursday" => 4, "Friday" => 5, "Saturday" => 6, "Sunday" => 7];
    
        return VolunteerSchedule::all()
            ->groupBy(['assignment', fn ($item) => $item['scheduled_days']])
            ->sortBy(fn ($val, $key) => $days[$key]);
    }