2010-08-17 6 views
2

나는 그것이 내가 문제는이 같은 재귀를 사용하여 일반적으로 달성 할 수 있다고 생각이재귀 함수는 PHP

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

과 같은 배열이 시나리오는 한 I 많은 시간에 걸쳐 나타납니다.

나는 중첩 된 배열 키를 구성하는 키의 배열에서 이것을 멀리 통과했습니다.

$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); 
} 
+0

이것은 재귀와 관련이없는 것 같습니다. 다른 접근 방식을 시도해보십시오. – muhmuhten

답변

0

원유하지만 작동 솔루션입니다.

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')));  
+0

시나리오에 대한 대우를 감사했습니다. –

3

당신은 단지 루프 재귀가 필요하지 않습니다 :

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

*/ 
+0

그것이 필요한 모든 것은 아니지만 올바른 생각입니다. – Borealid

+0

감사합니다. 지금은 일반화해야합니다. –

+0

올바른 방향으로 갈 수 있도록 모든 노력을 기울여야합니다. – webbiedave

0

재귀를? 아니야. 이 시도 :

function add_role($dataArray, $userid, $project_code, $role) 
{ 
    $dataArray[$userid][$project_code][] = $role; 
} 
0

기능 솔루션 :이 고차원 적 기능으로

$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" 
    } 
    } 
}