Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用点表示法在PHP中展开数组_Php_Arrays_Recursion - Fatal编程技术网

如何使用点表示法在PHP中展开数组

如何使用点表示法在PHP中展开数组,php,arrays,recursion,Php,Arrays,Recursion,我的php数组结构如下: array( 'servicemanagement.scheduler.events.edit' => 'Edit', 'servicemanagement.scheduler.events.delete' => 'Delete', 'servicemanagement.scheduler.events' => 'Events', 'servicemanagement.scheduler' => 'Schedule

我的php数组结构如下:

array(
    'servicemanagement.scheduler.events.edit' => 'Edit',
    'servicemanagement.scheduler.events.delete' => 'Delete',
    'servicemanagement.scheduler.events' => 'Events',
    'servicemanagement.scheduler' => 'Scheduler',
    'servicemanagement.subscribers' => 'Subscribers',
    'servicemanagement.subscribers.index' => 'Index',
    'servicemanagement' => 'Service management',
);
我想将is转换为多维数组,如:

array(
    'servicemanagement' => array(
        'id' => 'servicemanagement',
        'title' => 'Service Management',
        'children' => array(
            'scheduler' => array(
                'id' => 'servicemanagement.scheduler',
                'title' => 'Scheduler',
                'children' => array(
                    'events' => array(
                        'id' => 'servicemanagement.scheduler.events',
                        'title' => 'Events',
                        'children' => array(
                            'edit' => array(
                                'id' => 'servicemanagement.scheduler.events.edit',
                                'title' => 'Edit',
                                'children' => array(),
                            ),
                            'delete' => array(
                                'id' => 'servicemanagement.scheduler.events.delete',
                                'title' => 'Delete',
                                'children' => array(),
                            ),
                        ),
                    ),
                ),
            ),
            'subscribers' => array(
                'id' => 'servicemanagement.subscribers',
                'title' => 'Subscribers',
                'children' => array(
                    'index' => array(
                        'id' => 'servicemanagement.subscribers.index',
                        'title' => 'Index',
                    )
                ),
            ),
        ),
    ),
);
我已经检查了一些答案,比如:

但我似乎无法清除数组顶部的写入内容,最后一条记录“servicemanagement”删除了所有以前的记录

这里使用的功能是

function setArray(&$array, $keys, $value) {
    $keys = explode(".", $keys);
    $current = &$array;
    foreach($keys as $key) {
        $current = &$current[$key];
    }
    $current = $value;
}
我发现的另一个功能,但没有达到预期的效果,是:

function unflatten($array,$prefix = '')
{
    $result = array();
    foreach($array as $key=>$value)    {
        if (!empty($prefix)) {
            $key = preg_replace('#^'.preg_quote($prefix).'#','',$key);
        }
        if (strpos($key,'.') !== false) {
            parse_str('result['.str_replace('.','][',$key)."]=".$value);
        } else {
            $result[$key] = $value;
        }
    }
    return $result;
}
由于所有记录的结束格式都相同,因此可以选择使用递归来取消该数组的格式设置


有人能给我一个提示吗?

这不是最干净的解决方案,但它作为一个单一的功能工作

    $your_array = array(
        'servicemanagement.scheduler.events.edit' => 'Edit',
        'servicemanagement.scheduler.events.delete' => 'Delete',
        'servicemanagement.scheduler.events' => 'Events',
        'servicemanagement.scheduler' => 'Scheduler',
        'servicemanagement.subscribers' => 'Subscribers',
        'servicemanagement.subscribers.index' => 'Index',
        'servicemanagement' => 'Service management',
    );

    function expand($array, $level = 0)
    {
        $result = array();
        $next = $level + 1;

        foreach($array as $key=>$value) {
            $tree = explode('.', $key);
            if(isset($tree[$level])) {
                if(!isset($tree[$next])) {
                    $result[$tree[$level]]['id'] =  $key;
                    $result[$tree[$level]]['title'] = $value;
                    if(!isset($result[$tree[$level]]['children'])) {
                        $result[$tree[$level]]['children'] = array();
                    }
                } else {
                    if(isset($result[$tree[$level]]['children'])) {
                        $result[$tree[$level]]['children'] = array_merge_recursive($result[$tree[$level]]['children'], expand(array($key => $value), $next));
                    } else {
                        $result[$tree[$level]]['children'] = expand(array($key => $value), $next);
                    }
                }

            }
        }

        return $result;

    }
   var_export(expand($your_array));

我在这里创建了一个
unflatten
函数供参考:

这受到以下资源的轻微影响:


Hm,我想你必须为此创建一个递归函数。我曾经回答过类似的问题,@Voitcus这是与文章中第一个示例类似的解决方案。我不知道问题到底是什么。当函数处理最后一行
servicemanagement
时,它会覆盖整个树,结果是
数组('servicemanagement'=>'servicemanagement');
这已经足够好了,它可以完成任务。我们可以用
$result[$tree[$level]]['id']=introde('.',array_slice($tree,0,$next));
替换为
$result[$tree[$level]]['id']=$key;
我刚刚更改了答案以适应它,因为它删除了不必要的逻辑。
$results = [
  'id' => 'abc123',
  'address.id' => 'def456',
  'address.coordinates.lat' => '12.345',
  'address.coordinates.lng' => '67.89',
  'address.coordinates.geo.accurate' => true,
];

function unflatten($data) {
  $output = [];
  foreach ($data as $key => $value) {
    $parts = explode('.', $key);
    $nested = &$output;
    while (count($parts) > 1) {
      $nested = &$nested[array_shift($parts)];
      if (!is_array($nested)) $nested = [];
    }
    $nested[array_shift($parts)] = $value;
  }
  return $output;
}

echo json_encode(unflatten($results));

/*
{
  "id": "abc123",
  "address": {
    "id": "def456",
    "coordinates": {
      "lat": "12.345",
      "lng": "67.89",
      "geo": {
        "accurate": true
      }
    }
  }
}
*/