如何通过子数组值对多维数组进行分组并在PHP中重新分配键

I looked at all the similar questions and samples (there are many) but still can't get this to work (though I think I am close).

I have an array of employee schedules pulled from a text file...

schedule.txt:

    123,Joe,20120208,0845,1645
    123,Joe,20120209,0800,1600
    456,Sue,20120208,0900,1700
    456,Sue,20120209,0700,1500
    ...

My code to generate the array is:

    $schedule = file_get_contents('./schedule.txt');
    $s = explode("
", $schedule);
    for ($i = 0; $i < count($s); $i++) {
        $s[$i] = explode(",", $s[$i]);
    }
    print_r($s);

Output is:

    Array
    (
        [0] => Array
            (
                [0] => 123
                [1] => Joe
                [2] => 20120208
                [3] => 0845
                [4] => 1645
            )

        [1] => Array
            (
                [0] => 123
                [1] => Joe
                [2] => 20120209
                [3] => 0800
                [4] => 1600
            )

        [2] => Array
            (
                [0] => 456
                [1] => Sue
                [2] => 20120208
                [3] => 0900
                [4] => 1700
            )

        [3] => Array
            (
                [0] => 456
                [1] => Sue
                [2] => 20120209
                [3] => 0700
                [4] => 1500
            )
    )

I am instead trying to group employees by Id in a new multidimensional array with output like this:

    Array
    (
        [123] => Array
            (
                [0] => Array
                    (
                        [0] => Joe
                        [1] => 20120208
                        [2] => 0845
                        [3] => 1645
                    )

                [1] => Array
                    (
                        [0] => Joe
                        [1] => 20120209
                        [2] => 0800
                        [3] => 1600
                    )
            )

        [456] => Array
            (
                [0] => Array
                    (
                        [0] => Sue
                        [1] => 20120208
                        [2] => 0900
                        [3] => 1700
                    )

                [1] => Array
                    (
                        [0] => Sue
                        [1] => 20120209
                        [2] => 0700
                        [3] => 1500
                    )
            )
    )

I cannot for the life of me wrap my head around how to change my existing array into this new (different) output... I am trying this but getting nowhere:

    $newArr = array();

    foreach($s as $k => $v) {
        if(!isset($newArr[$v[0]])) {
            $newArr[$v[0]] = array();
        }

        $newArr[$v[0]][] = array($v[0]);
    }

Though my output is now:

    Array
    (
        [123] => Array
            (
                [0] => Array
                    (
                        [0] => 123
                    )

                [1] => Array
                    (
                        [0] => 123
                    )
            )

        [456] => Array
            (
                [0] => Array
                    (
                        [0] => 456
                    )

                [1] => Array
                    (
                        [0] => 456
                    )
            )
    )

Any thoughts? I know I am missing something in my code around the line:

    $newArr[$v[0]][] = array($v[0]);

I tried changing it to:

    $newArr[$v[0]][] = array(0 => $v[1], 1 => $v[2], 2 => $v[3], 3 => $v[4]);

which gives my the right output, but I now get undefined offset errors. Plus, if the number of keys in the sub array changes, this code is now limited to the 4 I explicitly entered...

this should be enough, if I understood you right :)

$lines = file('./schedule.txt');

$employees = array();
foreach ($lines as $line)
{
    $chunks = explode(',', $line);
    $employees[$chunks[0]][] = array_slice($chunks, 1);
}

print_r($employees);
<?php
//read the file into an array with each line being an entry
$schedule = file('./schedule.txt');
//empty array
$s = array();
//loop through file lines
foreach($schedule as $row){
    //explode on comma
    $row = explode(",", trim($row));
    //if the id doesn't exist yet...
    if(!isset($s[$row[0]])){
        //...make it an empty array
        $s[$row[0]] = array();
    }
    //add the row under the id
    $s[$row[0]][] = $row;
}
print_r($s);
?>

You can use fscanf:

$handle    = fopen('./schedule.txt', 'r');
$employees = array();
while ($line = fscanf($handle, '%d,%s')) {
  $employees[$line[0]][] = explode(',', $line[1]);
}
fclose($handle);

print_r($employees);

There is a function called fgetcsv to easily grab comma separated values. No need to do it yourself.

This code also solves your problem and properly handles blank lines:

if (($handle = fopen("schedules.csv", "r")) !== FALSE) {

    $schedules = array();
    while (($data = fgetcsv($handle)) !== FALSE) {
        if ($data[0] !== null) { //blank lines return an array containing null
            $schedules[$data[0]][] = array_slice($data, 1);
        }
    }
    fclose($handle);

    //do what you need to

} else {
    // file failed to open
}

Note that I named the file .csv instead of .txt. I'd recommend that you save things that are comma separated values as .csv files. Maybe even define what each column is in the file as well.