如何从数组转换隐式嵌套

时间:2015-04-20 15:12:34

标签: php arrays

给出一个看起来像这样的PHP数组:

[
  'foo' => 1,
  'bar[0]' => 6,
  'bar[1]' => 7,
  'bar[2]' => 8,
  'baz' => 'anything',
  ... and so on
]

我想将“隐含的”嵌套转换为真正的数组,而其余部分保持不变,导致:

[
  'foo' => 1,
  'bar' => [6, 7, 8],
  'baz' => 'anything',
]

我搜索过php文档,但找不到实用程序。我确信我可以写一个功能来做这件事,但感觉就像重新发明轮子一样。当然这样的功能已经存在了吗?

2 个答案:

答案 0 :(得分:2)

您可以使用array_walk()preg_match来查看密钥是否应该是"数组"。然后我们可以通过引用传入我们的最终数组,以允许我们编辑它。

例如

<?php

$a = [
  'foo' => 1,
  'bar[0]' => 6,
  'bar[1]' => 7,
  'bar[2]' => 8,
  'baz' => 'anything',
];

$end = [];

array_walk($a, function($val, $key) use(&$end) {
    //See if the key is something like "bar[1]"
    if( preg_match("/^([a-z]+)\[[0-9]+\]$/", $key, $match) ) {
       //See if "bar" key exists in our final array, if not create it.
       if( array_key_exists($match[1], $end) == FALSE ) {
         return $end[$match[1]] = array($val);
       }
       //Add value to array we created above
       return $end[$match[1]][] = $val;
    }
    //It's just a normal key, so just add it to our final array
    return $end[$key] = $val;
});

print_r($end);

https://eval.in/315998

答案 1 :(得分:1)

只是在玩耍。请参阅注释以获取代码说明。

  /*
  our source array
  */
  $a = array(
     'foo' => 1,
     'bar[0]' => 6,
     'bar[1]' => 7,
     'bar[2]' => 8,
     'baz' => 'anything'
  );

  // an array declared to hold all variable names present in array.
  $vars = array();

  /*
  http://php.net/manual/en/function.extract.php
  extract all values from the array with keys are variable names. Keys like 
  bar[0] do not make sense to extract function so it ignores them.
  */
  extract($a);

  /*
  Now that we've got all variables we possibly could using extract(), we
  traverse the source array to create the $bar array ourselves.
  */
  foreach($a as $k => $v) {
     /* 
     if key contains a [
     this check could be rigorous, but I leave that to the production code developer
     */
     if(strstr($k, '[')) {

        /*
        replace the [number] part from key to get the array name, i.e., "bar"
        */
        $arr_name = preg_replace('/\[\d+\]/', '', $k);

        /*
        using variable variables feature (http://php.net/manual/en/language.variables.variable.php)
        check if we've created the array already. if not, create now. and
        record the variable name in $vars array for future reference
        */
        if(!is_array($$arr_name)) {
           $$arr_name = array();
           $vars[] = $arr_name;
        }

        /*
        formulate and eval() (http://php.net/manual/en/function.eval.php) 
        a statement that inserts current $v into our created array
        eval is evil so do some rigorous testing before using it
        */
        eval('$' . $k . '=' . $v . ';');
     }
     else{
        //otherwise just record the variable.
        $vars[] = $k;
     }
  }

  /* $vars holds names of all variables you got from stream */
  var_dump($vars);
  /* display the variables */
  var_dump($foo, $bar, $baz);


 /* almost forgot, http://php.net/manual/en/function.var-dump.php */