title: PHP - Recursively set each array element's key to the value of a child element when given the childs key name
body: <p>I'll start by showing a non-recursive example </p>
  
  <p><strong>Non- recursive example</strong> </p>
  
  <pre><code>$given_key_name = 'site_id';
  
  $rows[] = array(
      'site_id' =&gt; '0',
      'language_id' =&gt; '1',
      'name' =&gt; 'sitename',
      'description' =&gt;'site desc',
  );
  
  $results = array();
  foreach($rows as $row){
      $key_value = $row[$given_key_name];
      unset($row[$given_key_name]);
      $results[$key_value] = $row;
  }
  
  //  OR This method is faster than the forloop
  
  $results = array_combine(array_column($rows, $given_key_name),$rows);
  foreach($results as &amp;$row){
      unset($row[$given_key_name]); 
  }
  </code></pre>
  
  <p><strong><code>$results</code> Equals</strong></p>
  
  <pre><code>$results[0] = array( 
      'language_id' =&gt; '1',
      'name' =&gt; 'sitename',
      'description' =&gt;'site desc',
  );
  </code></pre>
  
  <p>Simple, the key name has been set to the value of the given child element. But I would like to be able to nest and unnest by using multiple key names.</p>
  
  <p>Example </p>
  
  <p><code>$given_key_names = array('site_id', 'language_id');</code></p>
  
  <p>In this case the required result would be. </p>
  
  <p><code>$results[0][1] = array( 
      'name' =&gt; 'sitename',
      'description' =&gt;'site desc',
   );</code></p>
  
  <p><strong>Explanation</strong></p>
  
  <p>The first keys value has been used as the first key in the $results array and a new empty array is created as its value. <code>$results[0] = array();</code> </p>
  
  <p>As there is a second key, its value is set as a key to the newly created array and its value is also a new empty array. <code>$results[0][1] = array()</code>; </p>
  
  <p>As there are no more keys the empty array is populated with the remaining values</p>
  
  <p><code>$results[0][1] = array( 
      'name' =&gt; 'sitename',
      'description' =&gt;'site desc',
   );</code></p>
  
  <p>so i would like two functions <code>nestByKeyNames</code> and <code>unNestByKeyName</code>.</p>
  
  <h3>NestByKeyNames Function</h3>
  
  <p><a href="https://stackoverflow.com/a/33959924/2273611">Christians Answer solves this</a></p>
  
  <pre><code>function nestByKeyNames($arrayRows, $arrayKeyOrder){
  
      // Prepare resulting array
      $arrayResult = array();
  
      // Cycle the input array
      foreach($arrayRows as $someRow){
          // We will acomplish this using references
          $current = &amp;$arrayResult;
  
          // get the current level
          foreach($arrayKeyOrder as $someKey){
              $someValue = $someRow[$someKey];
              if(isset($current[$someValue])){
                  $current = &amp;$current[$someValue];
              }else{
                  $current[$someValue] = array();
                  $current = &amp;$current[$someValue];
              }
              unset($someRow[$someKey]);
          }
          $current = $someRow;
      }
      return $arrayResult;
  }
  </code></pre>
  
  <p>I wonder whether <code>array_combine(array_column($arrayRows, $key_name),$arrayRows);</code> could be used instead of the first iteration to improve performance?</p>
  
  <p>This represents the results from a mysql select statement.</p>
  
  <pre><code>$rows = array(
      array(
          'pri_id_1' =&gt;1,
          'pri_id_2' =&gt;1,
          'pri_id_3' =&gt;1,
          'col_1' =&gt;'col_value_1111',
          'col_2' =&gt;'col_value_1112',
          'col_3' =&gt;'col_value_1113',
      ),
      array(
          'pri_id_1' =&gt;1,
          'pri_id_2' =&gt;2,
          'pri_id_3' =&gt;1,
          'col_1' =&gt;'col_value_1211',
          'col_2' =&gt;'col_value_1212',
          'col_3' =&gt;'col_value_1213',
      ),
      array(
          'pri_id_1' =&gt;1,
          'pri_id_2' =&gt;3,
          'pri_id_3' =&gt;1,
          'col_1' =&gt;'col_value_1311',
          'col_2' =&gt;'col_value_1312',
          'col_3' =&gt;'col_value_1313',
      )
  );
  
  $keyNames = array('pri_id_1','pri_id_2','pri_id_3');
  $results = nestByKeyNames($rows, $keyNames);
  </code></pre>
  
  <p>The following output is produced </p>
  
  <pre><code>Array
  (
      [1] =&gt; Array
          (
              [1] =&gt; Array
                  (
                      [1] =&gt; Array
                          (
                              [col_1] =&gt; col_value_1111
                              [col_2] =&gt; col_value_1112
                              [col_3] =&gt; col_value_1113
                          )
  
                  )
  
              [2] =&gt; Array
                  (
                      [1] =&gt; Array
                          (
                              [col_1] =&gt; col_value_1211
                              [col_2] =&gt; col_value_1212
                              [col_3] =&gt; col_value_1213
                          )
  
                  )
  
              [3] =&gt; Array
                  (
                      [1] =&gt; Array
                          (
                              [col_1] =&gt; col_value_1311
                              [col_2] =&gt; col_value_1312
                              [col_3] =&gt; col_value_1313
                          )
  
                  )
  
          )
  
  )
  </code></pre>
  
  <h3>UnNestByKeyNames Function</h3>
  
  <p>unNestByKeyNames should be able to take this output and convert it back to the original array providing that it is given the key names. 
  <a href="https://stackoverflow.com/a/33959924/2273611">Christians Answer</a> did not solves this as it doesnt work with a single key name but i can tell its very close.</p>
  
  <pre><code>function unNestByKeyNames($arrayRows, $arrayKeyOrder){
  
  
  }
  
  $keyNames = array('pri_id_1','pri_id_2','pri_id_3');
  $rows = unNestKeyNames($results, $keyNames);
  </code></pre>
  
  <p>My true goal is to take the results from MYSQL <code>SELECT</code> statement and populate a form using the same naming convention by using <code>nestByKeyNames</code>. </p>
  
  <p>e.g.</p>
  
  <pre><code>&lt;input name="rows[1][1][1][col_1]" value="col_value_1" /&gt;
  </code></pre>
  
  <p>and then convert the $_POST request back into an MYSQL <code>INSERT</code> statement by  first using <code>unNestByKeyNames</code>.</p>
  
  <p>From this i will create an <code>INSERT</code> statement. </p>
  
  <pre><code>function returnValues($rows, $column_names){
  
      //validation has been removed for clarity
  
      $implode_VALUES = array();
  
      foreach ($rows as $key =&gt; $row) {
          $implode_row_values = array();
          foreach ($column_names as $column_name) {
              $implode_row_values[$column_name] = $row[$column_name];
          }
          if($implode_row_values){
              $implode_VALUES[] = " ('" . implode("','", $implode_row_values) . "') ";
          }
      }
      return $implode_VALUES;
  }
  
  $implode_COLUMNS = array('pri_id_1','pri_id_2','pri_id_3','col_1','col_2','col_3');
  
  $implode_VALUES = returnValues($rows, $implode_COLUMNS)
  
  $sql = "INSERT INTO table_name (" . implode(',', $implode_COLUMNS) . ") VALUES " . implode(',', $implode_VALUES);
  </code></pre>
  
  <p>The final result should produce a sql statement like so </p>
  
  <p><code>INSERT INTO table_name (pri_id_1,pri_id_2,pri_id_3,col_1,col_2,col_3) VALUES  ('1','1','1','NEW_value_1111','NEW_value_1112','NEW_value_1113') , ('1','2','1','NEW_value_1211','NEW_value_1212','NEW_value_1213') , ('1','3','1','NEW_value_1311','NEW_value_1312','NEW_value_1313')</code></p>
  
  <p>What I Would like</p>
  
  <ul>
  <li>Improvement suggestions on the 'nestByKeyNames' function (performance/ does it have bugs)</li>
  <li>help producing 'unNestByKeyNames' code</li>
  <li>Improvement suggestions on my '$rows to mysql INSERT' approach </li>
  <li>examples of how i could make any of my code perform better.</li>
  </ul>