PHP - Recursively set each array element's key to the value of a child element when given the childs key name PHP - Recursively set each array element's key to the value of a child element when given the childs key name arrays arrays

PHP - Recursively set each array element's key to the value of a child element when given the childs key name


This was trickier than I first imagined but I believe I have a messy solution.

First of all, this is the data I am working with. dumpr is a custom function that formats var_dump better.

$arrayKeyOrder = array(    'site_id',    'language_id');$original = array(    array(        'site_id' => '0',        'language_id' => '1',        'name' => 'sitename',        'description' =>'site desc',    ),    array(        'site_id' => '0',        'language_id' => '2',        'name' => 'sitename',        'description' =>'site desc',    ),    array(        'site_id' => '1',        'language_id' => '1',        'name' => 'sitename',        'description' =>'site desc',    ),    array(        'site_id' => '2',        'language_id' => '1',        'name' => 'sitename',        'description' =>'site desc',    ),);$zipped = doZip($original, $arrayKeyOrder);$unzipped = unZip($zipped, $arrayKeyOrder);dumpr($original);dumpr($zipped);dumpr($unzipped);

Here is the zip and unzip functions:

function doZip($arrayRows, $arrayKeyOrder){    // Prepare resulting array    $arrayResult = array();    // Cycle the input array    foreach($arrayRows as $someRow){        // We will acomplish this using references        $current = &$arrayResult;        // get the current level        foreach($arrayKeyOrder as $someKey){            $someValue = $someRow[$someKey];            if(isset($current[$someValue])){                $current = &$current[$someValue];            }else{                $current[$someValue] = array();                $current = &$current[$someValue];            }            unset($someRow[$someKey]);        }        $current = $someRow;    }    return $arrayResult;}function unZip($arrayRows, $arrayKeyOrder, $arrayValues = array(), $depth = 0){    $arrayResults = array();    if($depth < count($arrayKeyOrder)){        foreach($arrayRows as $key => $value){            $arrayValues[$depth] = $key;            $arrayResults[] =  unZip($value, $arrayKeyOrder, $arrayValues, $depth + 1);        }    }else{        $extra = array_combine($arrayKeyOrder, $arrayValues);        $result = array_merge($extra, $arrayRows);        return $result;    }    if($depth == 0){        for($i = 1; $i < count($arrayKeyOrder); $i++){            $arrayResults = call_user_func_array('array_merge', $arrayResults);        }            }    return $arrayResults;}

And finally, here is the output. let me know if this is what you were asking for and if it worked OK on a larger data-set.

/vhost/virtual/sandbox/public/index.php:54array(4) {    [0] = array(4) {        [site_id] = string(1) "0"        [language_id] = string(1) "1"        [name] = string(8) "sitename"        [description] = string(9) "site desc"    }    [1] = array(4) {        [site_id] = string(1) "0"        [language_id] = string(1) "2"        [name] = string(8) "sitename"        [description] = string(9) "site desc"    }    [2] = array(4) {        [site_id] = string(1) "1"        [language_id] = string(1) "1"        [name] = string(8) "sitename"        [description] = string(9) "site desc"    }    [3] = array(4) {        [site_id] = string(1) "2"        [language_id] = string(1) "1"        [name] = string(8) "sitename"        [description] = string(9) "site desc"    }}/vhost/virtual/sandbox/public/index.php:55array(3) {    [0] = array(2) {        [1] = array(2) {            [name] = string(8) "sitename"            [description] = string(9) "site desc"        }        [2] = array(2) {            [name] = string(8) "sitename"            [description] = string(9) "site desc"        }    }    [1] = array(1) {        [1] = array(2) {            [name] = string(8) "sitename"            [description] = string(9) "site desc"        }    }    [2] = array(1) {        [1] = array(2) {            [name] = string(8) "sitename"            [description] = string(9) "site desc"        }    }}/vhost/virtual/sandbox/public/index.php:56array(4) {    [0] = array(4) {        [site_id] = int(1) 0        [language_id] = int(1) 1        [name] = string(8) "sitename"        [description] = string(9) "site desc"    }    [1] = array(4) {        [site_id] = int(1) 0        [language_id] = int(1) 2        [name] = string(8) "sitename"        [description] = string(9) "site desc"    }    [2] = array(4) {        [site_id] = int(1) 1        [language_id] = int(1) 1        [name] = string(8) "sitename"        [description] = string(9) "site desc"    }    [3] = array(4) {        [site_id] = int(1) 2        [language_id] = int(1) 1        [name] = string(8) "sitename"        [description] = string(9) "site desc"    }}


Try this:

// initialize your array$all_rows = array();// loop through query resultswhile( $row = $qry->fetch_assoc() ){    // temporarily store these vars for easy use later    $s_id = $row['site_id'];    $l_id = $row['language_id'];    // create an empty array based on site_id and language_id    $all_rows[ $s_id ][ $l_id ] = array();    // loop through all columns returned from query    foreach ( $row as $key => $val )    {        // if it's not one of the two primary keys, push it to the array        if ( ! in_array($key, $all_primary_keys) )        {            $all_rows[ $s_id ][ $l_id ][ $key ] = $val;        }    }}


Is there a reason the below wouldn't work?

$results = array();while($row = $qry->fetch_assoc()){    $results[$row['site_id']][$row['language_id']] = array(        'name'  =>  $row['name'],        'description' => $row['description']    );}