基于数组键将平面PHP数组转换为嵌套数组?

基于数组键将平面PHP数组转换为嵌套数组?,php,multidimensional-array,Php,Multidimensional Array,我需要将数组键指示结构的平面数组转换为父元素变为元素零的嵌套数组,即在示例中: $education['x[1]'] = 'Georgia Tech'; 它需要转换为: $education[1][0] = 'Georgia Tech'; 以下是一个示例输入数组: $education = array( 'x[1]' => 'Georgia Tech', 'x[1][1]' => 'Mechanical Engineering', 'x[1][2]' =&

我需要将数组键指示结构的平面数组转换为父元素变为元素零的嵌套数组,即在示例中:

$education['x[1]'] = 'Georgia Tech';
它需要转换为:

$education[1][0] = 'Georgia Tech';
以下是一个示例输入数组:

$education = array(
  'x[1]'     => 'Georgia Tech',
  'x[1][1]'  => 'Mechanical Engineering',
  'x[1][2]'  => 'Computer Science',
  'x[2]'     => 'Agnes Scott',
  'x[2][1]'  => 'Religious History',
  'x[2][2]'  => 'Women\'s Studies',
  'x[3]'     => 'Georgia State',
  'x[3][1]'  => 'Business Administration',
);
以下是输出应该是什么:

$education => array(
  1 => array(
    0 => 'Georgia Tech',
    1 => array( 0 => 'Mechanical Engineering' ),
    2 => array( 0 => 'Computer Science' ),
  ),
  2 => array(
    0 => 'Agnes Scott',
    1 => array( 0 => 'Religious History' ),
    2 => array( 0 => 'Women\'s Studies' ),
  ),
  3 => array(
    0 => 'Georgia State',
    1 => array( 0 => 'Business Administration' ),
  ),
);
我的头撞在墙上已经好几个小时了,但还是不能用。我想我已经看得太久了。提前谢谢

另外,它应该是完全可嵌套的,即它应该能够转换如下所示的密钥:

x[1][2][3][4][5][6] 

p.p.S.@Joseph Silber有一个聪明的解决方案,但不幸的是使用
eval()
不是一个选项,因为它是一个WordPress插件,WordPress社区正试图禁止使用
eval()

如果你总是用
[0]
存储数组中的第一个元素,那么你可以使用这个:

$education = array(
    'x[1][0]' => 'Georgia Tech',
    'x[1][1]' => 'Mechanical Engineering',
    'x[1][2]' => 'Computer Science',
    'x[2][0]' => 'Agnes Scott',
    'x[2][1]' => 'Religious History',
    'x[2][2]' => 'Women\'s Studies',
    'x[3][0]' => 'Georgia State',
    'x[3][1]' => 'Business Administration'
);

$x = array();

foreach ($education as $key => $val)
{
    eval('$'.$key.'=$val;');
}

print_r($x);

下面是一些代码,用于处理最初建议作为输出的内容

/**
 * Give it and array, and an array of parents, it will decent into the
 * nested arrays and set the value.
 */
function set_nested_value(array &$arr, array $ancestors, $value) {
  $current = &$arr;
  foreach ($ancestors as $key) {

    // To handle the original input, if an item is not an array, 
    // replace it with an array with the value as the first item.
    if (!is_array($current)) {
      $current = array( $current);
    }

    if (!array_key_exists($key, $current)) {
      $current[$key] = array();
    }
    $current = &$current[$key];
  }

  $current = $value;
}


$education = array(
  'x[1]'     => 'Georgia Tech',
  'x[1][1]'  => 'Mechanical Engineering',
  'x[1][2]'  => 'Computer Science',
  'x[2]'     => 'Agnes Scott',
  'x[2][1]'  => 'Religious History',
  'x[2][2]'  => 'Women\'s Studies',
  'x[3]'     => 'Georgia State',
  'x[3][1]'  => 'Business Administration',
);

$neweducation = array();

foreach ($education as $path => $value) {
  $ancestors = explode('][', substr($path, 2, -1));
  set_nested_value($neweducation, $ancestors, $value);
}
基本上,将数组键拆分为一个很好的祖先键数组,然后使用一个很好的函数使用这些父键进入$neweducation数组,并设置值

如果您希望更新帖子的输出,请在foreach循环中的“explode”行后面添加此内容

$ancestors[] = 0;
$education=array(
“x[1]”=>“乔治亚理工大学”,
“x[1][1]”=>“机械工程”,
“x[1][2]”=>“计算机科学”,
“x[2]”=>“Agnes Scott”,
“x[2][1]”=>“宗教史”,
“x[2][2]”=>“妇女研究”,
“x[3]”=>“乔治亚州”,
“x[3][1]”=>“工商管理”,
//取消注释以测试深嵌套。
//'x[1][2][3][4][5][6]=>'水下编织篮',
);
$newarray=array();
foreach($key=>$value的教育){
//解析出键的各个部分并将它们转换为整数。
$parts=分解(“[”,$key);
对于($i=1;$i
更新:修改解决方案以处理新需求。 更新:清理了变量名并添加了注释。(最后一次编辑,我保证:)

基于第一次,我通过修改$procents变量找到了一个适用于.ini文件的解决方案

编辑:以下是我的工作代码的完整版本:

我的阵列中有此设置,基于.ini文件:

[resources.db.adapter] => PDO_MYSQL
[resources.db.params.host] => localhost
[resources.db.params.dbname] => qwer
[resources.db.params.username] => asdf
[resources.db.params.password] => zxcv
[resources.db.params.charset] => utf8
[externaldb.adapter] => PDO_MYSQL
[externaldb.params.host] => localhost
[externaldb.params.dbname] => tyui
[externaldb.params.username] => ghjk
[externaldb.params.password] => vbnm
[externaldb.params.charset] => latin1
结果如所愿:

Array
(
[resources] => Array
    (
        [db] => Array
            (
                [adapter] => PDO_MYSQL
                [params] => Array
                    (
                        [host] => localhost
                        [dbname] => qwer
                        [username] => asdf
                        [password] => zxcv
                        [charset] => utf8
                    )

            )

    )

[externaldb] => Array
    (
        [adapter] => PDO_MYSQL
        [params] => Array
            (
                [host] => localhost
                [dbname] => tyui
                [username] => ghjk
                [password] => vbnm
                [charset] => latin1
            )

    )

)


非常麻烦…介意我问一下输入结果如何…?@PlaqueEditor这就是如何使用自定义WordPress插件将其存储为wp_Posteta中的meta_键。当遇到诸如
x[2][2]
之类的键时,您如何知道它应该是
x[2][2]=“whatever”
还是
x[2][2][0]='随便什么'
?@Joseph Silber-问得好。也许它应该始终是
x[2][2][0]。
让我想一想。@Joseph Silber-很好。我认为我的输出示例有问题。我已经更新了,我的更新是否更有意义?(注意,这会导致我的头旋转,所以我可能仍然有“错误”。)谢谢你的帮助。聪明,谢谢,但我应该提到使用
eval()
不是一个选项。如果$val包含任何双引号(“)您的代码将导致解析错误。您应该使用var_export来避免这种情况。哦,还有一点——您使用的是eval,因此,不要使用var_export或简单的值内插,而是使用变量:eval(“$”。$key.=$val;;:)回答得好,谢谢,但与@Joseph Silber,
eval()
不是用于此用例的选项。我知道,而且我也知道存储这种结构也不好。如果可能的话,我将尝试找出快速但安全的解决方案。自php 5.3起,魔法引号就被弃用,自php 5.4起被删除,所以如果您仍在使用它,请删除它it@stereofrog-你能给我举一个魔术引语的例子吗问题?感谢Advaln.RealMFoO——在一个理想的世界中,魔术引号将被丢弃,但在WordPress的遗留世界中,核心团队做出了不放弃它的决定(参见:):任何WordPress插件都必须考虑它是活跃的。我想,这可以处理一个密钥可以有两个以上级别的情况,即<代码> x [1 ] [ 2 ] [ 3 ] [4 ] [5 ] [6 ]。“
?没有。我被移动目标问题缠住了。我已经更新了我的解决方案。但我更喜欢realmfoo或Logan F.Smyth。有趣的问题!很好!我永远不会自己想出代码,但据我所知,它工作得很好。谢谢。自从它工作以来,我没有时间尝试不同的方法。我知道这是多年来的事了但这正是我需要的,谢谢!
$result = array();

foreach( $education as $path => $value ) {

    $parts = explode('][', trim( $path, 'x[]' ) );
    $target =& $result;

    foreach( $parts as $part )
        $target =& $target[$part];

    $target = array($value);
}

var_dump($result);
//$ancestors = explode('][', substr($path, 2, -1));
$ancestors = explode('.', $path);
[resources.db.adapter] => PDO_MYSQL
[resources.db.params.host] => localhost
[resources.db.params.dbname] => qwer
[resources.db.params.username] => asdf
[resources.db.params.password] => zxcv
[resources.db.params.charset] => utf8
[externaldb.adapter] => PDO_MYSQL
[externaldb.params.host] => localhost
[externaldb.params.dbname] => tyui
[externaldb.params.username] => ghjk
[externaldb.params.password] => vbnm
[externaldb.params.charset] => latin1
Array
(
[resources] => Array
    (
        [db] => Array
            (
                [adapter] => PDO_MYSQL
                [params] => Array
                    (
                        [host] => localhost
                        [dbname] => qwer
                        [username] => asdf
                        [password] => zxcv
                        [charset] => utf8
                    )

            )

    )

[externaldb] => Array
    (
        [adapter] => PDO_MYSQL
        [params] => Array
            (
                [host] => localhost
                [dbname] => tyui
                [username] => ghjk
                [password] => vbnm
                [charset] => latin1
            )

    )

)