好的,这是一个很长的解决方案,您可能希望将其包装到一个函数中。只需将其复制并粘贴到空白文档中,然后在浏览器中检查结果。
<pre>
<?php
$orig = array(
array('name' => 'A', 'hierarchy' => '1'),
array('name' => 'B', 'hierarchy' => '1.2'),
array('name' => 'C', 'hierarchy' => '1.3'),
array('name' => 'D', 'hierarchy' => '1.3.1')
//,array('name' => 'E', 'hierarchy' => '1.2.1')
//,array('name' => 'F', 'hierarchy' => '2.1')
);
function special_sort($arr1,$arr2) {
$h1 = $arr1['hierarchy'];
$h2 = $arr2['hierarchy'];
$ch1 = count($h1);
$ch2 = count($h2);
if ($ch1 < $ch2) return -1;
if ($ch1 > $ch2) return 1;
return $h1 > $h2 ? 1 : ($h1 < $h2 ? -1 : 0);
}
// this first checks lengths and then values
// so 1.3 gets -1 against 1.2.1 whereas
// 1.3.2 still gets 1 against 1.3.1
$temp = $orig;
// temporary array to keep your original untouched
foreach ($temp as &$arr) {
$arr['hierarchy'] = explode('.',$arr['hierarchy']);
// turn hierachy numbers into arrays for later
// sorting purposes
}
unset($arr);
// get rid of the reference used in the loop
usort($temp,'special_sort');
// sort by the sort function above
echo '<h2>$orig</h2>'; print_r($orig);
echo '<h2>$temp</h2>'; print_r($temp);
// for you to see what it looks like now
$res = array();
// our final array
// by the following loop we're using the hierarcy
// numbers as keys to push into the result array
foreach ($temp as $arr) {
$h = $arr['hierarchy'];
if (count($h) == 1) {
// this is for those with single hierarchy
// numbers such as 1, 2, etc.
$res[$h[0]] = array('name'=>$arr['name']);
continue;
}
if (!isset($res[$h[0]]))
$res[$h[0]] = array('name'=>'');
// if, say this is 2.1 but there is no 2 in the array then
// we need to create that. see the last commented item in
// the original array. uncomment it to see why I wrote this
$newLoc =& $res[$h[0]];
// reference of the new place in result
// array to push the item
for ($i = 1; $i < count($h); $i++) {
if (!isset($newLoc['children']))
$newLoc['children'] = array();
// create children array if it doesn't exist
if (!isset($newLoc['children'][$h[$i]]))
$newLoc['children'][$h[$i]] = array();
// create children[hierarch key] array if it doesn't exist
$newLoc =& $newLoc['children'][$h[$i]];
// update reference
}
$newLoc = array('name'=>$arr['name']);
// assign the new name to this reference
unset($newLoc);
// get rid of the reference
}
unset($temp);
// get rid of the array now that we're done with it
echo '<h2>$res</h2>'; print_r($res);
function fix_keys($array) {
foreach ($array as $k => $val) {
if (is_array($val)) $array[$k] = fix_keys($val);
}
if(is_numeric($k)) return array_values($array);
return $array;
}
// function courtesy of Lobos,
// http://stackoverflow.com/a/12399408/913097
$endRes = fix_keys($res);
// create the end result array. this is actually
// a copy of the $res array except the numeric
// keys were reset.
unset($res);
// get rid of the last unused array
echo '<h2>$endRes</h2>'; print_r($endRes);
?>
</pre>