Php 使用foreach按组和人员对数组进行排序

Php 使用foreach按组和人员对数组进行排序,php,arrays,foreach,Php,Arrays,Foreach,我正在尝试将数组分为组和人 问题是,当我使用计数器“pos_group=0”时,它只显示每个类一个人,但如果我将其设置为负数,并在“if”中增加它,如果我得到结果 在分配新数组时,我是否在做其他事情 <?php $data = [ 0 => [ 'g_id' => 22, 'g_name' => 'ABC', 'u_id' => 1, 'u_name'=> 'Pepe' ]

我正在尝试将数组分为组和人

问题是,当我使用计数器“pos_group=0”时,它只显示每个类一个人,但如果我将其设置为负数,并在“if”中增加它,如果我得到结果

在分配新数组时,我是否在做其他事情

<?php

   $data = [
    0 => [
        'g_id' => 22,
        'g_name' => 'ABC',
        'u_id' => 1,
        'u_name'=> 'Pepe'
    ],
    1 => [
        'g_id' => 22,
        'g_name' => 'ABC',
        'u_id' => 2,
        'u_name'=> 'Mario'
    ],
    2 => [
        'g_id' => 22,
        'g_name' => 'ABC',
        'u_id' => null,
        'u_name'=> null
    ],
    3 => [
        'g_id' => 31,
        'g_name' => 'CDE',
        'u_id' => 3,
        'u_name'=> 'Juan'
    ],
    4 => [
        'g_id' => 41,
        'g_name' => 'EFG',
        'u_id' => 4,
        'u_name'=> 'Pedro'
    ],
    
];


    $last_group_id = null;
    $pos_group = 0;
    foreach ($data as $group_user):
        
        //Add Groups
        if($last_group_id != $group_user['g_id']){
            //$pos_group ++;
            $final[$pos_group]  = [
                'g_id' => $group_user['g_id'],
                'g_name' => $group_user['g_name']
            ];
            
            //$last_group_id = $group_user['g_id'];
            //$pos_group ++;
            
            
        }
        
        //Add Members
        if(!is_null($group_user['u_id'])){
            $final[$pos_group]['members'][$group_user['u_id']] = [
                'u_id' => $group_user['u_id'],
                'u_name' => $group_user['u_name']
            ];
        }

        if($last_group_id != $group_user['g_id']){
            $pos_group ++;
            $last_group_id = $group_user['g_id'];
        }
    endforeach;

    echo "<pre>";
    print_r($final);
    //var_dump($final);
    echo "</pre>";

?>
我仅通过将变量设置为-1并在“if”之后增加计数器来获得该结果,如下所示:

$final = [];
foreach ($data as $groupUser) {
    if (null !== $groupUser['u_id']) {
        /* Note that for the final array I use the group id as key. That way
        instead of tracking the current position and last group, you can simply
        add at the group id index. I am also overwriting the group info every time
        instead of checking if it exists (for simplicity), becuase there is no harm
        done since it will always be the same. */
        $final[$groupUser['g_id']]['g_id'] = $groupUser['g_id'];
        $final[$groupUser['g_id']]['g_name'] = $groupUser['g_name'];
        // add member, we've already checked the id against null
        $final[$groupUser['g_id']]['members'][$groupUser['u_id']] = [
            'u_id' => $groupUser['u_id'],
            'u_name' => $groupUser['u_name']
        ];
    }
}
这有点傻,但我找不到问题XD


谢谢

它与计数器增量的位置有关。第一种情况在循环结束时递增,而第二种情况在循环早期递增。让我们观察在第一种情况下发生的情况(最后递增):

  • 第一次迭代
  • $pos\u组
    为0
  • 在索引0处添加了一个新组(id为22)
  • 在该组(Pepe)中添加新成员
  • $pos_group
    增加到1
    • 第二次迭代
  • $pos_组
    为1
  • 未添加组,因为它与上一个组相同
  • 添加了一个新成员(Mario),但在索引1处,它将置于组之外(因为在
    $pos_组
    为0时添加了第一个成员)
  • $pos_组
    未增加
    • 第三次迭代
  • 此处不做任何更改,组相同,id为空
    • 第四次迭代
  • $pos_组
    仍然是1(在最后两次迭代中没有增量)
  • 在索引1处添加了一个新组,覆盖了可怜的马里奥
  • …算法正常继续,直到结束
  • 之所以会出现这种差异,是因为该组的前两个成员以不同的指数相加。在任何添加之前,在开始处增加
    $pos_group
    变量可以消除问题,从而给出正确的结果

    但我想为此提出一个简化算法:

    Array
    (
        [22] => Array...
        [31] => Array...
    
    无需多次检查,无需跟踪其他变量,还可以处理未排序的数据。唯一的区别是,我的解决方案将具有与组ID相同的顶级密钥:


    如果这对您来说是个问题,那么您所要做的就是从0开始抓取
    array\u值($final)
    以获得重新索引的数组。

    非常感谢您的回答,它非常详细。我用ID制作了一个版本,它工作得很好,但我忘记了有一个reindex函数,我不想用foreach遍历整个数组。非常感谢你!
    $final = [];
    foreach ($data as $groupUser) {
        if (null !== $groupUser['u_id']) {
            /* Note that for the final array I use the group id as key. That way
            instead of tracking the current position and last group, you can simply
            add at the group id index. I am also overwriting the group info every time
            instead of checking if it exists (for simplicity), becuase there is no harm
            done since it will always be the same. */
            $final[$groupUser['g_id']]['g_id'] = $groupUser['g_id'];
            $final[$groupUser['g_id']]['g_name'] = $groupUser['g_name'];
            // add member, we've already checked the id against null
            $final[$groupUser['g_id']]['members'][$groupUser['u_id']] = [
                'u_id' => $groupUser['u_id'],
                'u_name' => $groupUser['u_name']
            ];
        }
    }
    
    Array
    (
        [22] => Array...
        [31] => Array...