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'] );}