分层数据到数组

时间:2012-12-07 09:57:30

标签: php

我已经搜索了好几天但似乎无法找到答案。 我有一个像

这样的数组
$startArray = 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')
);

我想去

$endResult = 
    array(
          array('name' => 'A', 
            'children' => array(
               array('name'=> 'b'), 
               array('name'=> 'c', 
                 'children' => array('name' => 'D')
               )
            )
    );

有什么建议吗? 感谢

2 个答案:

答案 0 :(得分:2)

好的,这是一个很长的解决方案,您可能希望将其包装到函数中。只需将其复制并粘贴到空白文档中,然后在浏览器中检查结果即可。

<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>

答案 1 :(得分:0)

如果没有正确的数组,则会重写这些值。你需要大约:

$arr = array(
  array('name' => 'a', 'hierarchy' => '1'),
  array('name' => 'b', 'hierarchy' => '1.2'),
);