Mam płaską strukturę tablicy ($rows) z tablicą kolumn ($groupByCols), którą chcę pogrupować według:

$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
    ]
];

Przechodząc przez zmienną $rows i odwołując się do każdej z wartości $groupByCols w kolejności, chcę uzyskać następującą tablicę hierarchiczną:

$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
            ]
        ]
    ]
];

Jestem w 99% pewien, że muszę użyć do tego rekurencji, ale po wypróbowaniu około 10 różnych rzeczy (z których żadna nie zadziałała), nie mogę dowiedzieć się, jak uzyskać to, czego chcę.

Normalnie podzieliłbym się kodem, który napisałem do tej pory, ale po kilkudniowym zastanowieniu się nad tym i nigdzie nie doszedłem, naprawdę nie mam wiele do pokazania.

Myślę, że potrzebuję tylko ogólnych wskazówek, w jaki sposób mogę (przypuszczalnie) rekurencyjnie używać zmiennych $groupByCols i $rows, aby uzyskać tablicę $groupedRows. Każda pomoc byłaby bardzo mile widziana.

Należy również pamiętać, że powyższe dane są bardzo proste w celach demonstracyjnych. Rzeczywiste dane mogą być nieskończenie dłuższe i bardziej złożone i być może będę musiał zejść w dół o 5-6 poziomów za pomocą $groupByCols, w zależności od charakteru tego, co jest wymagane.

Dziękuję Ci.

0
HartleySan 2 listopad 2018, 13:58

1 odpowiedź

Najlepsza odpowiedź

Ta funkcja zrobi to, co chcesz. Przechodzi przez tablicę, grupując według wartości zindeksowanych przez pierwszą wartość w $columns. Jeśli w tablicy $columns pozostały kolumny, rekursywnie grupuje według tych kolumn. Aby uniknąć dziwnie ponumerowanych klawiszy, wywołuje array_values, aby ponownie zindeksować wynik do klawiszy numerycznych zaczynających się od 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));

Wynik jest taki, jak chcesz, ale zamiast zaśmiecać odpowiedź długim drukiem, po prostu zobacz demo na 3v4l.org.

1
Nick 2 listopad 2018, 15:05