我甚至不确定如何开始写这个问题,但基本上,我有一个数组,看起来像这样:
Array
(
[0] => /
[1] => /404/
[2] => /abstracts/
[3] => /abstracts/edit/
[4] => /abstracts/review/
[5] => /abstracts/view/
[6] => /admin/
[7] => /admin/ads/
[8] => /admin/ads/clickcounter/
[9] => /admin/ads/delete/
[10] => /admin/ads/edit/
[11] => /admin/ads/list/
[12] => /admin/ads/new/
[13] => /admin/ads/sponsordelete/
[14] => /admin/ads/sponsoredit/
[15] => /admin/ads/sponsornew/
[16] => /admin/ads/stats/
[17] => /admin/boilerplates/
[18] => /admin/boilerplates/deleteboiler/
[19] => /admin/boilerplates/editboiler/
[20] => /admin/boilerplates/newboilerplate/
[21] => /admin/calendar/event/add/
[22] => /admin/calendar/event/copy/
)
我需要'减少'/'处理'它到一个看起来像这样的数组:
Array
(
[''] => Array()
['404'] => Array()
['abstracts'] => Array
(
[''] => Array()
['edit'] => Array()
['review'] => Array()
['view'] => Array()
)
['admin'] => Array
(
['ads'] => Array
(
[''] => Array()
['clickcounter'] => Array()
['delete'] =>Array()
['edit'] => Array()
)
)
.....
.....
)
那,如果手动初始化将看起来像这样:
$urlTree = array( '' => array(),
'404' => array(),
'abstracts'=> array( '' => array(),
'edit' => array(),
'review'=> array(),
'view' => array() ),
'admin' => array( 'ads'=> array( '' => array(),
'clickcounter'=> array(),
'delete' => array(),
'edit' => array() ) )
);
我通常偏离直接询问SO上的一大块代码,但有没有人可能有任何建议/代码可以遍历我的数组并将其转换为层次结构?
编辑:以下是我现在所拥有的一点,我知道这是一个可怜的小事,我今天只是把它搞清楚了。
function loadUrlData()
{
// hold the raw data, /blah/blah/
$urlData = array();
$res = sql::query( "SELECT DISTINCT(`url`) FROM `pages` ORDER BY `url` ASC" );
while( $row = sql::getarray( $res ) )
{
$urlData[] = explode( '/', substr( $row['url'], 1, -1 ) );
}
// populated, eventually, with the parent > child data
$treeData = array();
// a url
foreach( $urlData as $k=> $v )
{
// the url pieces
foreach( $v as $k2=> $v2 )
{
}
}
// $treeData eventually
return $urlData;
}
答案 0 :(得分:2)
看起来相当容易。您希望遍历所有行(foreach
),将它们拆分为多个部分(explode
),循环遍历它们(foreach
)并对它们进行分类。
由于您不喜欢要求大量代码,我不会提供任何代码。
<强>更新强>
解决这个问题的一个非常好的方法是引用$urlTree
(使用&
),循环遍历URL的每个部分,并继续将像$currentPosition
这样的变量更新到URL中的当前部分树。因为您使用&
,所以您可以直接编辑数组,同时仍使用简单变量。
更新2
这可能有效:
// a url
foreach( $urlData as $k=> $v )
{
$currentSection = &$treeData;
// the url pieces
foreach( $v as $k2=> $v2 )
{
if (!isset($currentSection[$v2])) {
$currentSection[$v2] = array();
}
$currentSection = &$currentSection[$v2];
}
}
答案 1 :(得分:2)
我知道你没有要求一大堆代码,但我只是称之为小服务:
$map = array();
foreach($urls as $url) {
$folders = explode('/', trim($url, '/'));
applyChain($map, $folders, array());
}
function applyChain(&$arr, $indexes, $value) { //Here's your recursion
if(!is_array($indexes)) {
return;
}
if(count($indexes) == 0) {
$arr = $value;
} else {
applyChain($arr[array_shift($indexes)], $indexes, $value);
}
}
这很简单。我们将每个url分隔到其文件夹中(删除尾部和前导斜杠),然后沿阵列链向下工作,直到我们到达URL中提到的文件夹。然后我们在那里放置一个新的空数组并继续下一个URL。
答案 2 :(得分:1)
$arr = array(
'/',
'/404/',
'/abstracts/',
'/abstracts/edit/',
'/abstracts/review/',
'/abstracts/view/',
'/admin/',
'/admin/ads/',
'/admin/ads/clickcounter/',
'/admin/ads/delete/',
'/admin/ads/edit/',
'/admin/ads/list/',
'/admin/ads/new/',
'/admin/ads/sponsordelete/',
'/admin/ads/sponsoredit/',
'/admin/ads/sponsornew/',
'/admin/ads/stats/',
'/admin/boilerplates/',
'/admin/boilerplates/deleteboiler/',
'/admin/boilerplates/editboiler/',
'/admin/boilerplates/newboilerplate/',
'/admin/calendar/event/add/',
'/admin/calendar/event/copy/');
$result = array();
foreach ($arr as $node) {
$result = magic($node, $result);
}
var_dump($result);
function magic($node, $tree)
{
$path = explode('/', rtrim($node, '/'));
$original =& $tree;
foreach ($path as $node) {
if (!array_key_exists($node, $tree)) {
$tree[$node] = array();
}
if ($node) {
$tree =& $tree[$node];
}
}
return $original;
}
答案 3 :(得分:1)
我的版本:
<?php
$srcArray = array(
0 => '/',
1 => '/404/',
2 => '/abstracts/',
3 => '/abstracts/edit/',
4 => '/abstracts/review/',
5 => '/abstracts/view/',
6 => '/admin/',
7 => '/admin/ads/',
// ....
);
$tree = array();
foreach($srcArray as $str){
$tmp = &$tree;
$parts = explode('/', rtrim($str, '/'));
foreach($parts as $part){
if(!array_key_exists($part, $tmp)){
$tmp[$part] = array();
}
$tmp = &$tmp[$part];
}
}
var_dump($tree);
答案 4 :(得分:1)
<?php
$old_array = array("/", "/404/", "/abstracts/", "/abstracts/edit/", "/abstracts/review/", "/rrl/");
$new_array = array();
foreach($old_array as $woot) {
$segments = explode('/', $woot);
$current = &$new_array;
for($i=1; $i<sizeof($segments); $i++) {
if(!isset($current[$segments[$i]])){
$current[$segments[$i]] = array();
}
$current = &$current[$segments[$i]];
}
}
print_r($new_array);
?>
答案 5 :(得分:0)
您可以考虑将文本转换为JSON字符串,然后使用json_decode()生成结构。