Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Mike Swan's avatar

Looking for help to format a collection out of two other collection.

Hi all,

I'm having some trouble creating a particular collection and looking for any advice. Below I will show what I have and then what result I'm looking for. Any help would be much appreciated.

What I have:

$shifts = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 ]);

$employeeIds = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);

Essentially the shift ids represent each week of the year and the employee needs to be a assigned multiple shifts based other factors. The closest I've come is using the chunkWhile method but haven't gotten what I need yet.

What I need: $sets = [ ['employee' => 1, 'set' => [0, 18, 36, 52]], ['employee' => 2, 'set' => [1, 19, 37]], ['employee' => 3, 'set' => [2, 20, 38]], ['employee' => 4, 'set' => [3, 21, 39, 17]], ['employee' => 5, 'set' => [4, 22, 40]], ['employee' => 6, 'set' => [5, 23, 41, 16]], ['employee' => 7, 'set' => [6, 24, 42]], ['employee' => 8, 'set' => [7, 25, 43]], ['employee' => 9, 'set' => [8, 26, 44]], ['employee' => 10, 'set' => [9, 27, 45]], ['employee' => 11, 'set' => [10, 28, 46, 35]], ['employee' => 12, 'set' => [11, 29, 47, 34]], ['employee' => 13, 'set' => [12, 30, 48]], ['employee' => 14, 'set' => [13, 31, 49]], ['employee' => 15, 'set' => [14, 32, 50]], ['employee' => 16, 'set' => [15, 33, 51]], ];

Thanks for any suggestions!

0 likes
3 replies
LaryAI's avatar
Level 58

To achieve the desired collection structure where each employee is assigned to specific shifts based on a pattern, you can use a combination of looping and conditional logic to distribute the shifts among the employees. Here's a possible solution using Laravel's collection methods:

$shifts = collect(range(0, 52));
$employeeIds = collect(range(1, 16));

// Initialize an empty collection to store the final sets
$sets = collect();

// Loop through each employee ID
foreach ($employeeIds as $employeeId) {
    // Calculate the shifts for each employee based on their ID
    $employeeShifts = $shifts->filter(function ($shift) use ($employeeId, $employeeIds) {
        return ($shift % $employeeIds->count()) == ($employeeId - 1);
    });

    // Add the result to the sets collection
    $sets->push([
        'employee' => $employeeId,
        'set' => $employeeShifts->values()->all()
    ]);
}

// Output the result
print_r($sets->all());

Explanation:

  1. Initialize Collections: We start by creating collections for shifts and employee IDs.
  2. Create an Empty Collection for Sets: This will store the final structured data.
  3. Loop Through Each Employee: For each employee, we determine which shifts they should be assigned.
  4. Filter Shifts: The filter method is used to select shifts for each employee. The condition inside the filter ensures that the shift is distributed evenly based on the employee's ID. The modulo operation (%) helps in evenly distributing shifts among employees.
  5. Add to Sets Collection: Each employee's ID and their corresponding shifts are added to the sets collection.
  6. Output the Result: Finally, we print out the sets collection.

This solution ensures that each employee is assigned shifts in a round-robin fashion, and it dynamically adjusts based on the total number of shifts and employees.

coni's avatar

Maybe something like this will meet Your requirements:

$shifts = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52]);

$employeeIds = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);

$sets = $employeeIds->map(fn ($item) => [
    'employee' => $item,
    'set' => $shifts->random(3)->toArray()
]);
1 like
Mike Swan's avatar

@Coni Thanks @Coni. The problem is I need a little more control with the shift number. Some employees will have a limit of 2 or 3 or 4 based on some other factors.

The A.I. answer provided was pretty much exactly what I needed. Pretty spooky how it works.

The % operator is something new to me and I think that's what I was looking for.

Thanks for the reply!

1 like

Please or to participate in this conversation.