开发者

Grouping a 2D array according to its values

开发者 https://www.devze.com 2023-01-19 13:54 出处:网络
I\'ve been trying to get some display logic to behave and stay where it belongs and the code has turned into an interesting little problem that\'d be nice to make a general solution for.

I've been trying to get some display logic to behave and stay where it belongs and the code has turned into an interesting little problem that'd be nice to make a general solution for.

Bear with me, it looks like a wall of text but I've tried to format it nicely with simple example data so it should be understandable after a quick skim through.

If for some reason this whole thing is a terrible idea, I need telling before I create an affront to the gods.

Starting with data like this, for example:

$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',
    ),

);

With an array of key names by which to group the data, such as

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

The data then becomes:

$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'开发者_Python百科 => 'Chicago',
            ),
        ),
        '21' => array(
            array(
                'name' => 'John',
                'age'  => '21',
                'city' => 'Chicago',
            ),
        ),
    ),
);

When I say "general solution", I mean I'm trying to make something that can group things to any nesting level depending on how many of the key names you ask it to group by.

It feels like the sort of problem that I could solve instantly if I just knew some random esoteric bit of PHP syntax. Any suggestions? I'll try to update this is if I figure it out in the meantime.


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;
}


I know this is old but wanted to post a solution for others when they come to it.

foreach($data as $row) {
     $data_array[$row['city']][] = $row;
}


I was originally trying to sort arrays of objects so since I was gonna write it anyway, here's one that works on objects, even if it is a slightly hacky idea

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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消