2011-11-17 229 views
1

我在PHP中,並且有一個看起來像這樣的數組。單個維數組,其鍵是括號字符串。將非嵌套和括號數組轉換爲嵌套數組

array(
    'matrix[min_rows]' => '0', 
    'matrix[max_rows]' => '', 
    'matrix[col_order][]' => 'col_new_1', 
    'matrix[cols][col_new_0][type]' => 'text', 
    'matrix[cols][col_new_1][type]' => 'text', 
    'matrix[cols][col_new_0][label]' => 'Cell 1', 
    'matrix[cols][col_new_1][label]' => 'Cell 2', 
    'matrix[cols][col_new_0][name]' => 'cell_1', 
    'matrix[cols][col_new_1][name]' => 'cell_2', 
    'matrix[cols][col_new_0][instructions]' => '', 
    'matrix[cols][col_new_1][instructions]' => '', 
    'matrix[cols][col_new_0][width]' => '33%', 
    'matrix[cols][col_new_1][width]' => '', 
    'matrix[cols][col_new_0][settings][maxl]' => '', 
    'matrix[cols][col_new_0][settings][fmt]' => 'none', 
    'matrix[cols][col_new_0][settings][content]' => 'all', 
    'matrix[cols][col_new_1][settings][maxl]' => '140', 
    'matrix[cols][col_new_1][settings][multiline]' => 'y', 
    'matrix[cols][col_new_1][settings][fmt]' => 'none', 
    'matrix[cols][col_new_1][settings][content]' => 'all', 
) 

是否有將其轉換成一個正常的嵌套數組沒有簡單的方法,即:

array(
    'matrix' => array(
     'min_rows' => '0', 
     'max_rows' => '', 
     'col_order' => array('col_new_1'), 
     'cols' => array(
      'col_new_0' => array(
       'type' => 'text', 
       'label' => 'Cell 1', 
....etc.... 

這是我目前的解決方案,但我在想,如果有更多的東西本地或高效:

foreach ($decoded_field_type_settings as $key => $value) 
{ 
    if (preg_match_all('/\[(.*?)\]/', $key, $matches)) 
    { 
     $new_key = substr($key, 0, strpos($key, '[')); 

     if (! isset($field_type_settings[$new_key])) 
     { 
      $field_type_settings[$new_key] = array(); 
     } 

     $array =& $field_type_settings[$new_key]; 

     $count = count($matches[1]) - 1; 

     foreach ($matches[1] as $i => $sub_key) 
     { 
      if (! $sub_key) 
      { 
       if ($i < $count) 
       { 
        $array[] = array(); 
       } 
       else 
       { 
        $array[] = $value; 
       } 
      } 
      else 
      { 
       if (! isset($array[$sub_key])) 
       { 
        if ($i < $count) 
        { 
         $array[$sub_key] = array(); 
        } 
        else 
        { 
         $array[$sub_key] = $value; 
        } 
       } 
      } 

      if ($i < $count) 
      { 
       $array =& $array[$sub_key]; 
      } 
     } 
    } 
    else 
    { 
     $field_type_settings[$key] = $value; 
    } 
} 

更新:我在下面發佈了一個答案。

+1

什麼是原始數據的來源是什麼? – 2011-11-17 21:50:09

+0

這是一個由jQuery.serializeArray()填充的隱藏表單字段。我捎帶第三方應用程序,所以我無法更改此數據。 – Rob

+0

我剛剛發佈了一個使用'http_build_query()'和'parse_str()'的答案,但是重新閱讀了你的問題,發現你已經有了這個答案。問題是,您沒有將解決方案作爲答案發布。請編輯您的問題以刪除解決方案,將解決方案作爲答案發布,並將其標爲綠色勾號(這樣您的問題就被視爲已解決)。哦,你已經6年沒有在現場了。 – mickmackusa

回答

0

這是最簡單的解決方案,不涉及正則表達式解析:

$original_array = array(
    'matrix[min_rows]' => '0', 
    'matrix[max_rows]' => '', 
    'matrix[col_order][]' => 'col_new_1', 
    'matrix[cols][col_new_0][type]' => 'text', 
    'matrix[cols][col_new_1][type]' => 'text', 
    'matrix[cols][col_new_0][label]' => 'Cell 1', 
    'matrix[cols][col_new_1][label]' => 'Cell 2', 
    'matrix[cols][col_new_0][name]' => 'cell_1', 
    'matrix[cols][col_new_1][name]' => 'cell_2', 
    'matrix[cols][col_new_0][instructions]' => '', 
    'matrix[cols][col_new_1][instructions]' => '', 
    'matrix[cols][col_new_0][width]' => '33%', 
    'matrix[cols][col_new_1][width]' => '', 
    'matrix[cols][col_new_0][settings][maxl]' => '', 
    'matrix[cols][col_new_0][settings][fmt]' => 'none', 
    'matrix[cols][col_new_0][settings][content]' => 'all', 
    'matrix[cols][col_new_1][settings][maxl]' => '140', 
    'matrix[cols][col_new_1][settings][multiline]' => 'y', 
    'matrix[cols][col_new_1][settings][fmt]' => 'none', 
    'matrix[cols][col_new_1][settings][content]' => 'all', 
); 

$query_string = http_build_query($original_array); 

$final_array = array(); 

parse_str($query_string, $final_array); 

var_dump($final_array); 
1

這可能會實現,但它可能會產生一些警告:

$matrix = array(); 
foreach($arr as $key => $value) { 
    eval('$' . $key . ' = \'' . $value . '\';'); 
} 

var_dump($matrix); 
+0

我正要提出這個想法。除了做一個大型的標記工作,這是我能想到的唯一有效的想法..醜陋的,但工程... –

+0

評估鍵的代碼?玩的開心! – hakre

+0

我也想過eval,雖然我通常聽說你應該避免出於安全目的,等等......這裏有什麼要考慮的嗎? (也許你至少可以確保字符串沒有分號或$符號或什麼...?) – joshuahedlund

0

看來,OP想,作爲輸出,一個數組聲明可直接通過PHP解析。所以我建議使用var_export()

$array = array(
    'matrix[min_rows]' => '0', 
    // ...... 
    // ...... 
    // ...... 
    'matrix[cols][col_new_1][settings][content]' => 'all' 
); 

$matrix = array(); 

foreach ($array as $key => $value) 
{ 
    // fix missing quotes around array indexes 
    $key = str_replace(array("[", "]", "['']"), array("['", "']", "[]"), $key); 
    // fill PHP array 
    eval('$'.$key.' = $value;'); 
} 

var_export($matrix); 
0

我想這應該這樣做...

<?php 
function convert2dTo3d($source) { 
    $refs = array(); 
    $output = array(); 

    foreach ($source AS $key => $val) { 
     $tok = strtok($key, '[]'); 

     $prev_tok = NULL; 
     while ($tok !== FALSE) { 
      $this_ref =& $refs[$tok]; 

      if ($prev_tok === NULL) 
       $output[$tok] =& $this_ref; 
      else 
       $refs[$prev_tok][$tok] =& $this_ref; 

      $prev_tok = $tok; 
      $tok = strtok('[]'); 

      if ($tok === FALSE) 
       $refs[$prev_tok] = $val; 
     } 
    } 

    return $output; 
} 


// Test 
$source = array(
    'matrix[min_rows]' => '0', 
    'matrix[max_rows]' => '', 
    'matrix[col_order][]' => 'col_new_1', 
    'matrix[cols][col_new_0][type]' => 'text', 
    'matrix[cols][col_new_1][type]' => 'text', 
    'matrix[cols][col_new_0][label]' => 'Cell 1', 
    'matrix[cols][col_new_1][label]' => 'Cell 2', 
    'matrix[cols][col_new_0][name]' => 'cell_1', 
    'matrix[cols][col_new_1][name]' => 'cell_2', 
    'matrix[cols][col_new_0][instructions]' => '', 
    'matrix[cols][col_new_1][instructions]' => '', 
    'matrix[cols][col_new_0][width]' => '33%', 
    'matrix[cols][col_new_1][width]' => '', 
    'matrix[cols][col_new_0][settings][maxl]' => '', 
    'matrix[cols][col_new_0][settings][fmt]' => 'none', 
    'matrix[cols][col_new_0][settings][content]' => 'all', 
    'matrix[cols][col_new_1][settings][maxl]' => '140', 
    'matrix[cols][col_new_1][settings][multiline]' => 'y', 
    'matrix[cols][col_new_1][settings][fmt]' => 'none', 
    'matrix[cols][col_new_1][settings][content]' => 'all', 
); 

echo "<pre>"; 
print_r(convert2dTo3d($source)); 
echo "</pre>"; 
0

您可以使用一個簡單的,基於正則表達式解析器,基於存儲的每一個的每串中的信息來創建多維數組關鍵:

function parse_flat_matrix(array $flat) 
{ 
    $matrix = array(); 
    $varname = 'matrix'; 
    $nameToken = '[a-z0-9_]*'; 

    foreach($flat as $key => $value) 
    { 
     $keys = preg_split(sprintf('/(\[%s\])/', $nameToken), $key, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 

     if ($varname !== array_shift($keys)) 
     { 
      throw new InvalidArgumentException(sprintf('Invalid key %s.', $key)); 
     } 

     $p =& $matrix; 
     foreach($keys as $k) 
     { 
      $r = preg_match(sprintf('/^\[(%s)\]$/', $nameToken), $k, $kk); 
      if (!$r) 
      { 
       throw new InvalidArgumentException(sprintf('Invalid subkey %s in key %s.', $k, $key)); 
      } 

      if ('' === $kk[1]) 
      { 
       $p =& $p[]; 
      } 
      else 
      { 
       $p =& $p[$kk[1]]; 
      } 
     } 
     $p = $value; 
     unset($p); 
    } 

    return $matrix; 
} 

有了您的例子給出的數據,它將創建這個數組:

Array 
(
    [min_rows] => 0 
    [max_rows] => 
    [col_order] => Array 
     (
      [0] => col_new_1 
     ) 

    [cols] => Array 
     (
      [col_new_0] => Array 
       (
        [type] => text 
        [label] => Cell 1 
        [name] => cell_1 
        [instructions] => 
        [width] => 33% 
        [settings] => Array 
         (
          [maxl] => 
          [fmt] => none 
          [content] => all 
         ) 

       ) 

      [col_new_1] => Array 
       (
        [type] => text 
        [label] => Cell 2 
        [name] => cell_2 
        [instructions] => 
        [width] => 
        [settings] => Array 
         (
          [maxl] => 140 
          [multiline] => y 
          [fmt] => none 
          [content] => all 
         ) 

       ) 

     ) 

)