将非嵌套和括号数组转换为嵌套数组

时间:2011-11-17 21:45:49

标签: php arrays multidimensional-array

我在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;
    }
}

更新:我在下面发布了一个答案。

5 个答案:

答案 0 :(得分:1)

这可能有用,虽然它可能会产生一些警告:

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

var_dump($matrix);

答案 1 :(得分: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);

答案 2 :(得分: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>";

答案 3 :(得分: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
                        )

                )

        )

)

答案 4 :(得分: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);
相关问题