Как сделать этот плоский массив в PHP иерархическим без родительских идентификаторов? - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть плоская структура массива ($rows) с массивом столбцов ($groupByCols), по которому я хочу сгруппировать данные:

$groupByCols = ['a', 'b'];
$rows = [
    [
        'a' => 1,
        'b' => 10,
        'c' => 100
    ],
    [
        'a' => 1,
        'b' => 20,
        'c' => 200
    ],
    [
        'a' => 1,
        'b' => 20,
        'c' => 300
    ],
    [
        'a' => 1,
        'b' => 30,
        'c' => 400
    ],
    [
        'a' => 2,
        'b' => 40,
        'c' => 500
    ],
    [
        'a' => 2,
        'b' => 50,
        'c' => 600
    ],
    [
        'a' => 3,
        'b' => 60,
        'c' => 700
    ]
];

Перебирая переменную $rows и ссылаясь на каждое из значений $groupByCols по порядку, я хочу получить следующий иерархический массив:

$groupedRows = [
    [
        [
            [
                'a' => 1,
                'b' => 10,
                'c' => 100
            ]
        ],
        [
            [
                'a' => 1,
                'b' => 20,
                'c' => 200
            ],
            [
                'a' => 1,
                'b' => 20,
                'c' => 300
            ]
        ],
        [
            [
                'a' => 1,
                'b' => 30,
                'c' => 400
            ]
        ]
    ],
    [
        [
            [
                'a' => 2,
                'b' => 40,
                'c' => 500
            ]
        ],
        [
            [
                'a' => 2,
                'b' => 50,
                'c' => 600
            ]
        ]
    ],
    [
        [
            [
                'a' => 3,
                'b' => 60,
                'c' => 700
            ]
        ]
    ]
];

Я на 99% уверен, что для этого мне нужно использовать рекурсию, но, попробовав примерно 10 разных вещей (ни одна из которых не сработала), я не могу понять, как получить то, что хочу.

Обычно, я бы поделился кодом, который я написал до сих пор, но, подумав об этом в течение нескольких дней и никуда не денясь, мне действительно нечего показать.

Я думаю, что мне просто нужно общее руководство о том, как я могу (предположительно) рекурсивно использовать переменные $groupByCols и $rows для получения массива $groupedRows. Любая помощь будет принята с благодарностью.

Также обратите внимание, что приведенные выше данные очень просты для демонстрации. Реальные данные могут быть бесконечными длиннее и сложнее, и мне, возможно, придется опускаться на 5-6 уровней с помощью $groupByCols, в зависимости от характера того, что требуется.

Спасибо.

1 Ответ

0 голосов
/ 02 ноября 2018

Эта функция будет делать то, что вы хотите. Он проходит через массив, группируя по значениям, проиндексированным по первому значению в $columns. Если в массиве $columns остаются столбцы, он рекурсивно группируется по этим столбцам. Чтобы избежать нечетных ключей, он вызывает array_values для переиндексации результата в числовые ключи, начинающиеся с 0.

function group_by($array, $columns) {
    $new_arr = array();
    $column = array_shift($columns);
    foreach ($array as $arr) {
        $new_arr[$arr[$column]][] = $arr;
    }
    if (count($columns)) {
        foreach ($new_arr as &$arr) {
            $arr = group_by($arr, $columns);
        }
    }
    return array_values($new_arr);
}
print_r(group_by($rows, $groupByCols));

Вывод производится по вашему желанию, но вместо того, чтобы загромождать ответ длинной печатью, просто посмотрите демонстрацию на 3v4l.org .

...