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

时间:2012-02-16 23:13:06

标签: php multidimensional-array grouping

我查看了所有相似的问题和样本(有很多),但仍然无法使其工作(尽管我认为我很接近)。

我从文本文件中提取了一系列员工日程安排......

自定:


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

生成数组的代码是:


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

输出是:


    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
            )
    )

我试图通过Id在一个新的多维数组中对员工进行分组,输出如下:


    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
                    )
            )
    )

我不能为我的生活包围如何将我现有的数组更改为这个新的(不同的)输出... 我正在尝试这个但无处可去:


    $newArr = array();

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

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

虽然我的输出现在是:


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

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

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

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

有什么想法?我知道我在代码中遗漏了一些内容:


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

我尝试将其更改为:


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

这给了我正确的输出,但我现在得到未定义的偏移误差。另外,如果子数组中的键数发生变化,此代码现在仅限于我明确输入的4 ...

4 个答案:

答案 0 :(得分:4)

如果我理解你的话,这应该足够了。)

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

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

print_r($employees);

答案 1 :(得分:2)

有一个名为fgetcsv的函数可以轻松抓取逗号分隔值。不需要自己动手。

此代码也可以解决您的问题并正确处理空行:

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
}

请注意,我将文件命名为.csv而不是.txt。我建议您将逗号分隔值保存为.csv个文件。甚至可以定义文件中每列的内容。

答案 2 :(得分:1)

<?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);
?>

答案 3 :(得分:1)

您可以使用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);