我有这样的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',
);
我想转换为多维数组,如:
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',
)
),
),
),
),
);
我已经检查了一些像这样的答案: How to set a deep array in PHP
但似乎我无法清理数组顶部的写作,最后一条记录'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;
}
这是一个使用递归来解除此扁平化的选项,因为所有记录的结束格式都是相同的。
愿任何人给我一个提示吗?
答案 0 :(得分:2)
这不是最干净的解决方案,但它可以作为单一功能使用
$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));
答案 1 :(得分:0)
我创建了一个unflatten
函数以供参考:
https://gist.github.com/Gerst20051/b14c05b72c73b49bc2d306e7c8b86223
$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
}
}
}
}
*/
这受到以下资源的轻微影响: