Php 递归函数

Php 递归函数,php,arrays,multidimensional-array,Php,Arrays,Multidimensional Array,我有一个数组,看起来像这样 $dataArray = array ( 0 => array ( 'UserId' => '804023', 'ProjectCode' => 'RA1234', 'Role' => 'PI', ), 1 => array ( 'UserId' => '804023', 'ProjectCode' => 'RA1234', 'Role' => 'P

我有一个数组,看起来像这样

$dataArray = array (
  0 => 
  array (
    'UserId' => '804023',
    'ProjectCode' => 'RA1234',
    'Role' => 'PI',
  ),
  1 => 
  array (
    'UserId' => '804023',
    'ProjectCode' => 'RA1234',
    'Role' => 'PM',
  ),
  2 => 
  array (
    'UserId' => '804023',
    'ProjectCode' => 'A90123',
    'Role' => 'CI',
  ),
  3 => 
  array (
    'UserId' => '804023',
    'ProjectCode' => 'A20022',
    'Role' => 'PM',
  ),
)
$expected = array (
  804023 => 
  array (
    'RA1234' => 
    array (
      0 => 'PI',
      1 => 'PM',
    ),
    'A90123' => 
    array (
      0 => 'PI',
    ),
    'A20022' => 
    array (
      0 => 'CI',
    ),
  ),
)
我需要它看起来像这样

$dataArray = array (
  0 => 
  array (
    'UserId' => '804023',
    'ProjectCode' => 'RA1234',
    'Role' => 'PI',
  ),
  1 => 
  array (
    'UserId' => '804023',
    'ProjectCode' => 'RA1234',
    'Role' => 'PM',
  ),
  2 => 
  array (
    'UserId' => '804023',
    'ProjectCode' => 'A90123',
    'Role' => 'CI',
  ),
  3 => 
  array (
    'UserId' => '804023',
    'ProjectCode' => 'A20022',
    'Role' => 'PM',
  ),
)
$expected = array (
  804023 => 
  array (
    'RA1234' => 
    array (
      0 => 'PI',
      1 => 'PM',
    ),
    'A90123' => 
    array (
      0 => 'PI',
    ),
    'A20022' => 
    array (
      0 => 'CI',
    ),
  ),
)
我认为这可以通过使用递归来实现,因为我可能会多次遇到这种情况

到目前为止,我已经传入了一个组成嵌套数组键的键数组,即

$keys=array("UserId","projectCode","Role");
但我只是不知道从这里走到哪里,有什么建议吗

public function structureData(array $data, array $keys)
 {
  //$structuredData = array();


  foreach ($data as $key => $value)
  {
   $keyForData = array_slice($keys,0,1);


   $remainingKeys = $keys;
   array_shift($remainingKeys);

   if (!array_key_exists($value[$keyForData[0]], $structuredData))
   {

    $count=count($remainingKeys);


    $structuredData[$value[$keyForData[0]]] =array();
    // this returns as expected array(804023 =>array ()); but subsequent recursive calls with the remaining data fail



   }

  }
  return $structuredData);
}

您不需要递归,只需要一个循环:

foreach ($dataArray as $da) {
    $expected[$da['UserId']][$da['ProjectCode']][] = $da['Role'];
}

var_export($expected);

/* output:

array (
  804023 => 
  array (
    'RA1234' => 
    array (
      0 => 'PI',
      1 => 'PM',
    ),
    'A90123' => 
    array (
      0 => 'CI',
    ),
    'A20022' => 
    array (
      0 => 'PM',
    ),
  ),
)

*/

递归?不。试试这个:

function add_role($dataArray, $userid, $project_code, $role)
{
    $dataArray[$userid][$project_code][] = $role;
}
功能解决方案:

$t = array_gather_key($dataArray, function ($e) { return $e['UserId']; } );

$t = array_map(
    function ($e) {
        return array_gather_key($e,
            function ($e) { return $e['ProjectCode'];  },
            function ($e) { return $e['Role']; } );
     },
     $t
);
使用此高阶函数:

function array_gather_key($array, $func, $transf = null) {
    $res = array();
    foreach ($array as $elem) {
        $key = $func($elem);
        if (!array_key_exists($key, $res))
            $res[$key] = array();
        if ($transf === null)
            $res[$key][] = $elem;
        else
            $res[$key][] = $transf($elem);
    }
    return $res;
}
这使得:

array(1) { [804023]=> array(3) { ["RA1234"]=> array(2) { [0]=> string(2) "PI" [1]=> string(2) "PM" } ["A90123"]=> array(1) { [0]=> string(2) "CI" } ["A20022"]=> array(1) { [0]=> string(2) "PM" } } } 阵列(1){ [804023]=> 阵列(3){ [“RA1234”]=> 阵列(2){ [0]=> 字符串(2)“PI” [1]=> 字符串(2)“PM” } [“A90123”]=> 阵列(1){ [0]=> 字符串(2)“CI” } [“A20022”]=> 阵列(1){ [0]=> 字符串(2)“PM” } } }
一个粗糙但有效的解决方案

function structureData($data, $keys){                                           
    $out = array();                                                             
    foreach($data as $row){                                                     
        $subout = &$out;                                                        
        foreach(array_slice($keys, 0, -1) as $key){                             
            $value = $row[$key];                                                
            $subout = &$subout[$value];                                         
        }                                                                       
        $subout[] = $row[$keys[count($keys) - 1]];                              

    }                                                                           
    return $out;                                                                
}                                                                               

print_r(structureData($dataArray, array('UserId', 'ProjectCode', 'Role')));     

这似乎与递归无关。尝试另一种方法?这应该是他所需要的一切,让他朝着正确的方向前进。