按公共数组键分组

时间:2018-04-30 13:58:54

标签: php multidimensional-array

$sortMod = [
    [
        'group_id'  => 1,
        'group_name'=>'Home',
        'module_id' => 1,
        'mod_name'  => 'Home',
        'mod_link'  => '/home',
        'var_name'  => 'home'
    ], [
        'group_id'=> 2,
        'module_id' => 2,
        'mod_name' => 'Numbers',
        'mod_link' => '/number_mapping',
        'var_name' => 'numbermap'
    ], [
        'group_id'=> 2,
        'module_id' => 70,
        'mod_name' => 'DR Plan',
        'mod_link' => '/dr_plan',
        'var_name' => 'dr_plan'
    ], [
        'group_id'=> 3,
        'module_id' => 8,
        'mod_name' => 'Reporting',
        'mod_link' => '/reporting',
        'var_name' => 'reporting'
    ], [
        'group_id'=> 3,
        'module_id' => 80,
        'mod_name' => 'Scheduler',
        'mod_link' => '/scheduler',
        'var_name' => 'scheduler'
    ]
];

我想按group_id;

对结果进行分组
$sortMod = [
  [
    'group_id'  => 1,
    'group_name'=>'Home',
    'module_id' => 1,
    'mod_name'  => 'Home',
    'mod_link'  => '/home',
    'var_name'  => 'home'
  ], [
    'group_id'=> 2,
    [
      'module_id' => 2,
      'mod_name' => 'Numbers',
      'mod_link' => '/number_mapping',
      'var_name' => 'numbermap'
    ], [
      'module_id' => 70,
      'mod_name' => 'DR Plan',
      'mod_link' => '/dr_plan',
      'var_name' => 'dr_plan'
    ]
  ], [
    'group_id'=> 3,
    [
      'module_id' => 8,
      'mod_name' => 'Reporting',
      'mod_link' => '/reporting',
      'var_name' => 'reporting'
    ], [
      'module_id' => 80,
      'mod_name' => 'Scheduler',
      'mod_link' => '/scheduler',
      'var_name' => 'scheduler'
    ]
  ]
];

目前我有这个:

$groups = [];
$modules = array();

我正在迭代数组$sortMod并按group_id对其进行分组,其中出现多个module_id,即group_id 2和3其中包含多个模块。因此,结果将看起来如上所述。虽然我知道默认情况下我可以将标志变量$groupExist设置为false,并且当组被推入$groups数组时,该值将设置为false。然后使用if语句检查值是否为true,然后仅推送模块值:

foreach($sortMod as $val) {
  if(!array_key_exists($val['group_id'],$groups)){
    $groups[$val['group_id']] = [];
  }
  $groups[$val['group_id']][] = $val;
} 


echo '<pre>';
print_r($groups);
echo '<pre>';

4 个答案:

答案 0 :(得分:3)

您可以使用array_reduce对数组进行分组。如果您不想创建多维数组(如果该组只有一个元素),则可以使用array_map

$sortMod = .. //Your array here.

$grouped = array_reduce($sortMod, function($c, $v){
    $c[ $v['group_id'] ][] = $v;
    return $c;
}, array());

$result = array_map(function ($n) {
    if ( count($n) === 1 ) return $n[0];       //Since the group has one element. Return the element 0.

    $newN = array();                           //Contruct the new format for 2 or more elements.
    $newN['group_id'] = $n[0]['group_id'];     //Add the group_id
    foreach($n as $value)                      //Loop thru the array, remove the group_id and push.
    {
        unset($value['group_id']);
        $newN[] = $value;
    }

    return $newN;
}, $grouped );

echo "<pre>";
print_r( $result );
echo "</pre>";

这将导致:

Array
(
    [1] => Array
        (
            [group_id] => 1
            [group_name] => Home
            [module_id] => 1
            [mod_name] => Home
            [mod_link] => /home
            [var_name] => home
        )

    [2] => Array
        (
            [group_id] => 2
            [0] => Array
                (
                    [module_id] => 2
                    [mod_name] => Numbers
                    [mod_link] => /number_mapping
                    [var_name] => numbermap
                )

            [1] => Array
                (
                    [module_id] => 70
                    [mod_name] => DR Plan
                    [mod_link] => /dr_plan
                    [var_name] => dr_plan
                )

        )

    [3] => Array
        (
            [group_id] => 3
            [0] => Array
                (
                    [module_id] => 8
                    [mod_name] => Reporting
                    [mod_link] => /reporting
                    [var_name] => reporting
                )

            [1] => Array
                (
                    [module_id] => 80
                    [mod_name] => Scheduler
                    [mod_link] => /scheduler
                    [var_name] => scheduler
                )

        )

)

答案 1 :(得分:1)

你可以像这样使用通用的自定义函数:

function array_group_by($a, $i, $rem = true){
  foreach($a as $v){
    $k = $v[$i];
    if($rem){
      unset($v[$i]);
    }
    $t[$k][] = $v;
  }

  return $t;
}

echo '<pre>';
print_r(array_group_by($sortMod, 'group_id'));
echo '<pre>';

here是输出。

group id无论如何都应该是唯一的,而这个输出不是你特别想要的,它会使一个更有用的数组循环。

第一个键是group_id。组数组中包含的以下数组是&#34;模块&#34;。

或者,您可以使用array_group_by($sortMod, 'group_id', false);group_id保留在该数组中。

现在循环时:

foreach(array_group_by($sortMod, 'group_id') as $groupid => $modules){
  echo "$groupid is the group_id and contains " . count($modules) . " modules";
  foreach($modules as $module){
    echo "Hi from " . $module['module_id'];
  }
}

在我看来,简短且可重复使用的代码是可行的方法。

答案 2 :(得分:1)

对代码添加一些修改会产生类似的东西

$group = [];
foreach ($sortMod as $val){
    $current_id = $val['group_id'];
    unset($val['group_id']);
    if (!array_key_exists($current_id ,$group)){
        $group[$current_id] = array();
    }
    $group[$current_id][] = $val;
}

echo '<pre>';
print_r($groups);
echo '<pre>';

答案 3 :(得分:1)

您可以使用initializers/new_framework_defaults_5_2.rb$val添加到群组中。如果找到此密钥,则可以创建group_id密钥。如果你再次找到它并且它是一个数组,则附加它。

group_id

输出:

$groups = [];
foreach($sortMod as $val)
{
    $group_id = $val['group_id'];

    if (!isset($groups[$group_id])) { // First case
        $groups[$group_id] = $val ;
        continue;
    }

    // regroup if 'group_id' is not an array
    if (!is_array($groups[$group_id]['group_id']))
    {
        unset($groups[$group_id]['group_id']);
        $groups[$group_id] = ['group_id' => $group_id, $groups[$group_id]] ;
    }

    // append the new group
    unset($val['group_id']);
    $groups[$group_id][] = $val ;
}
// optionnal (to remove group_id keys)
$groups = array_values($groups);
print_r($groups);