Search code examples
phparraysmultidimensional-arraygroupingassociative-array

Convert an indexed array of associative arrays into a 3d associative array


The array is dynamic, can be with 7 ,more or less keys, except the first key never changes.

Array
(
    [0] => Array
        (
            [ProviderID] => 1010
            [ProviderName] => HAMZEPOUR, SHOKOUFEH                                                                                
        )
    [1] => Array
        (
            [ContactName] => ABC XYZ
            [Address1] => New York
            [AddressType] => Physical
        )
    [2] => Array
        (
            [ContactName] => ABC XYZ
            [Address1] => New York
            [AddressType] => Billing
        )
    [3] => Array
        (
            [ContactName] => ABC XYZ
            [Address1] => New York
            [AddressType] => Mailing
        )
    [4] => Array
        (
            [AlgorithmID] => 1
            [AlgoTitle] => Retro-Term
        )
    [5] => Array
        (
            [AlgorithmID] => 2
            [AlgoTitle] => Modifier 25 errors
        )
    [6] => Array
        (
            [HoldType] => HoldType
            [StatusID] => 1
        )
    [7] => Array
        (
            [HoldType] => HoldType
            [StatusID] => 1
        )
    [8] => Array
        (
            [HoldType] => Hold
            [StatusID] => 2
        )

)

I need change it to something like this:

Array
    (
        [ProviderInfo] => Array
            (
                [PORAProviderID] => 1010
                [ProviderName] => HAMZEPOUR, SHOKOUFEH                                                                                
            )
        [ProviderAddress] => Array
            (
            [Physical] => Array
                (
                    [ContactName] => ABC XYZ
                    [Address1] => New York
                    [AddressType] => Physical
                )
            [Billing] => Array
                (
                    [ContactName] => ABC XYZ
                    [Address1] => New York
                    [AddressType] => Billing
                )
            [Mailing] => Array
                (
                    [ContactName] => ABC XYZ
                    [Address1] => New York
                    [AddressType] => Mailing
                )
            )
        [ProviderAlgorithm] => Array
            (
                [0] => Array
                    (
                        [AlgorithmID] => 1
                        [AlgoTitle] => Retro-Term
                    )
                 [1] => Array
                    (
                       [AlgorithmID] => 2
                       [AlgoTitle] => Modifier 25 errors 
                    )
            )
        [ProviderException] => Array
            (
                [0] => Array
                    (
                        [HoldType] => HoldType
                        [StatusID] => 1
                    )
                [1] => Array
                    (
                        [HoldType] => HoldType
                        [StatusID] => 1
                    )
                [2] => Array
                    (
                        [HoldType] => Hold
                        [StatusID] => 2
                    )
            )

    )

The first array is what I fetch from db as result of SP with four result sets, I would like to organize the array the way that it look like in the second example.

I tried doing this:

$search_array = $array;
$countb = count($search_array);
$counta = count($search_array) - 1;

//echo $countb;
$key_search = array('AlgorithmID', 'PORAProviderID', 'ContactName', 'HoldType');
$key_new = array('ProviderAlgorithm', 'ProviderInfo', 'ProviderAddress', 'ProviderException');

$b = 0; 
while ($b <= $countb) {
  $a = 0;
  while ($a <= $counta) {
    if (array_key_exists($key_search[$b], $search_array[$a])) {
      $array[$key_new[$b]] = $array[$a];
      unset($array[$a]);
     // $a=$a-1;
    }
    $a++;
  }
  $b++;
}

And this is what I'm getting:

Array
    (
        [ProviderAlgorithm] => Array
            (
                [AlgorithmID] => 2
                [AlgoTitle] => Modifier 25 errors
             )
        [ProviderInfo] => Array
            (
                [PORAProviderID] => 1010
                [ProviderName] => HAMZEPOUR, SHOKOUFEH                                                                                
            )
        [ProviderAddress] => Array
            (
                [ContactName] => ABC XYZ
                [Address1] => New York
                [AddressType] => Mailing
            )
        [ProviderException] => Array
            (
                [HoldType] => HoldType
                [StatusID] => 1
            )
    )

Link where I'm trying new things


Solution

  • Why not use a foreach to iterate through the first array and then use a switch to detect which type of key->value pairs to expect like so:

    EDIT: Code immediately below is wrong. Correct answer added below this code.

    <?php
    
    $newArray = array();
    
    foreach($array as $arr) {
    
        $keys = array_keys($arr);
    
        switch($keys[0]) {
    
            case "PORAProviderID":
    
                if(!isset($newArray["ProviderInfo"])) {
                     $newArray["ProviderInfo"] = array();
                }
                $newArray["ProviderInfo"]["PORAProviderID"] = $arr[0];
                $newArray["ProviderInfo"]["ProviderName"] = $arr[1];
    
            break;
    
            case "ContactName":
    
                if(!isset($newArray["ProviderAddress"])) {
                     $newArray["ProviderAddress"] = array();
                }
                $newArray["ProviderAddress"][$arr[2]] = array();
                $newArray["ProviderAddress"][$arr[2]]["ContactName"] = $arr[0];
                $newArray["ProviderAddress"][$arr[2]]["Address1"] = $arr[1];
                $newArray["ProviderAddress"][$arr[2]]["AddressType"] = $arr[2];
    
            break;
    
            case "AlgorithmID":
    
                if(isset($newArray["ProviderAlgorithm"])) {
                    $count = count($newArray["ProviderAlgorithm"]);
                } else {
                    $newArray["ProviderAlgorithm"] = array();
                    $count = -1;
                }
                $count++;
                $newArray["ProviderAlgorithm"][$count] = array();
                $newArray["ProviderAlgorithm"][$count]["AlgorithmID"] = $arr[0];
                $newArray["ProviderAlgorithm"][$count]["AlgoTitle"] = $arr[1];
    
            break;
    
            case "HoldType":
    
                if(isset($newArray["ProviderException"])) {
                    $count = count($newArray["ProviderException"]);
                } else {
                    $newArray["ProviderException"] = array();
                    $count = -1;
                }
                $count++;
                $newArray["ProviderException"][$count] = array();
                $newArray["ProviderException"][$count]["HoldType"] = $arr[0];
                $newArray["ProviderException"][$count]["StatusID"] = $arr[1];
    
            break;
    
        }
    
    }
    
    ?>
    

    I am sure this can be super simplified, but I am going for understanding here as opposed to efficiency. Using this method, you can then check for the algorithms and exceptions as well, and it does not expect any length or limitation of number of records.

    EDIT: Fixed several mistakes and issues. I am not sure why PHP does not index the array when using foreach - I may need to brush up on my PHP functions. I apologize for the confusion. I am leaving the original solution above to display what not to do.

    <?php
       $array=array(
        0 => array
            (
                'PORAProviderID' => '1010',
                'ProviderName' => 'HAMZEPOUR, SHOKOUFEH',                                                                                
            ),
    
        1 => array
            (
                'ContactName' => 'ABC XYZ',
                'Address1' => 'New York',
                'AddressType' => 'Physical'
            ),
    
        2 => array
            (
                'ContactName' => 'ABC XYZ',
                'Address1' => 'New York',
                'AddressType' => 'Billing'
            ),
    
        3 => array
            (
                'ContactName' => 'ABC XYZ',
                'Address1' => 'New York',
                'AddressType' => 'Mailing'
            ),
    
        4 => array
            (
                'AlgorithmID' => 1,
                'AlgoTitle' => 'Retro-Term'
            ),
    
        5 => array
            (
                'AlgorithmID' => 1,
                'AlgoTitle' => 'Retro-Term'
            ),
    
        6 => array
            (
                'HoldType' => 'HoldType',
                'StatusID' => 1
            ),
    
        7 => array
            (
               'HoldType' => 'HoldType',
               'StatusID' => 1
            ),
        8 => array
            (
                'HoldType' => 'Hold',
                'StatusID' => 2
            )
    
    );
    
    $newArray = array();
    
    foreach($array as $arr) {
    
        $keys = array_keys($arr);
    
        switch($keys[0]) {
    
            case "PORAProviderID":
    
                if(!isset($newArray["ProviderInfo"])) {
                    $newArray["ProviderInfo"] = array();
                }
                $newArray["ProviderInfo"]["PORAProviderID"] = $arr["PORAProviderID"];
                $newArray["ProviderInfo"]["ProviderName"] = $arr["ProviderName"];
    
            break;
    
            case "ContactName":
    
                if(!isset($newArray["ProviderAddress"])) {
                    $newArray["ProviderAddress"] = array();
                }
                $newArray["ProviderAddress"][$arr['AddressType']] = array();
                $newArray["ProviderAddress"][$arr['AddressType']]["ContactName"] = $arr["ContactName"];
                $newArray["ProviderAddress"][$arr['AddressType']]["Address1"] = $arr["Address1"];
                $newArray["ProviderAddress"][$arr['AddressType']]["AddressType"] = $arr["AddressType"];
    
            break;
    
            case "AlgorithmID":
    
                if(isset($newArray["ProviderAlgorithm"])) {
                    $count = count($newArray["ProviderAlgorithm"]);
                } else {
                    $newArray["ProviderAlgorithm"] = array();
                    $count = 0;
                }
                $newArray["ProviderAlgorithm"][$count] = array();
                $newArray["ProviderAlgorithm"][$count]["AlgorithmID"] = $arr["AlgorithmID"];
                $newArray["ProviderAlgorithm"][$count]["AlgoTitle"] = $arr["AlgoTitle"];
    
            break;
    
            case "HoldType":
    
                if(isset($newArray["ProviderException"])) {
                    $count = count($newArray["ProviderException"]);
                } else {
                    $newArray["ProviderException"] = array();
                    $count = 0;
                }
                $newArray["ProviderException"][$count] = array();
                $newArray["ProviderException"][$count]["HoldType"] = $arr["HoldType"];
                $newArray["ProviderException"][$count]["StatusID"] = $arr["StatusID"];
    
            break;
    
        }
    
    }
    ?>
    

    I am pretty new to StackOverflow and I must apologize for making such a bad first impression.