Группировка 2D-массива по его значениям - PullRequest
3 голосов
/ 12 октября 2010

Я пытался заставить некоторую логику отображения вести себя и оставаться на своем месте, и код превратился в небольшую интересную проблему, для которой было бы неплохо найти общее решение.

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

Если по какой-то причине все это ужасная идея, мне нужно рассказать, прежде чем я сделаю оскорбление богам.

Начиная с таких данных, например:

$data = array(

    array(
        'name' => 'Dave',
        'age'  => '21',
        'city' => 'New York',
    ),
    array(
        'name' => 'Mike',
        'age'  => '19',
        'city' => 'Chicago',
    ),
    array(
        'name' => 'John',
        'age'  => '21',
        'city' => 'Chicago',
    ),
    array(
        'name' => 'Matt',
        'age'  => '19',
        'city' => 'New York',
    ),
    array(
        'name' => 'Luke',
        'age'  => '21',
        'city' => 'New York',
    ),

);

С массивом имен ключей, по которому группируются данные, например

$groups = array('city', 'age);

Данные затем становятся:

$data = array(

    'New York' => array(
        '21' => array(
            array(
                'name' => 'Dave',
                'age'  => '21',
                'city' => 'New York',
            ),
            array(
                'name' => 'Luke',
                'age'  => '21',
                'city' => 'New York',
            ),
        ),
        '19' => array(
            array(
                'name' => 'Matt',
                'age'  => '19',
                'city' => 'New York',
            ),
        ),
    ),
    'Chicago' => array(
        '19' => array(
            array(
                'name' => 'Mike',
                'age'  => '19',
                'city' => 'Chicago',
            ),
        ),
        '21' => array(
            array(
                'name' => 'John',
                'age'  => '21',
                'city' => 'Chicago',
            ),
        ),
    ),
);

Когда я говорю «общее решение», я имею в виду, что я пытаюсь создать что-то, что может группировать вещи на любом уровне вложенности, в зависимости от того, по скольким именам ключей вы просите сгруппировать их.

Это похоже на проблему, которую я мог бы решить мгновенно, если бы знал какой-то случайный эзотерический бит синтаксиса PHP. Какие-либо предложения? Я постараюсь обновить это, если я выясню это в то же время.

Ответы [ 3 ]

4 голосов
/ 12 октября 2010
function group_array($arr, $fields) {

    if(empty($fields) || !is_array($fields)) {
        return $arr;
    }

    $newarr = array(); // so that we always return an array
    $field = array_shift($fields);

    foreach($arr as $val) {
        $newarr[$val[$field]][] = $val;
    }

    foreach(array_keys($newarr) as $key) {
        // Since we shifted one field off before, this groups by the remaining
        $newarr[$key] = group_array($newarr[$key], $fields);
    }

    return $newarr;
}
3 голосов
/ 20 декабря 2011

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

foreach($data as $row) {
     $data_array[$row['city']][] = $row;
}
0 голосов
/ 12 октября 2010

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

function group_objects($array, $fields)
{
    if (empty($fields) || !is_array($fields)) {
        return $array;
    }

    $newArray = array();
    $field    = array_shift($fields);

    foreach ($array as $object) {
        $key = call_user_func(array($object, 'get' . ucwords($field)));
        $newArray[$key][] = $object;
    }

    foreach (array_keys($newArray) as $key) {
        $newArray[$key] = group_objects($newArray[$key], $fields);
    }

    return $newArray;
}
...