0

我的数据库吐出这样的数据层次结构数组:

Array(
    [0] => array(
        [level] => 0
        [wo_number] => foo1
        [parent] => NULL
    )
    [1] => array(
        [level] => 1
        [wo_number] => foo2
        [parent] => foo1
    )
    [2] => array(
        [level] => 2
        [wo_number] => bar1
        [parent] => foo2
    )
    [3] => array(
        [level] => 2
        [wo_number] => bar2
        [parent] => foo2
    )
    [4] => array(
        [level] => 2
        [wo_number] => bar3
        [parent] => foo2
    )
    [5] => array(
        [level] => 2
        [wo_number] => bar4
        [parent] => foo2
    )
    [6] => array(
        [level] => 2
        [wo_number] => bar5
        [parent] => foo2
    )
)

每个数组节点都有一个父键,它引用数组中的另一个节点。

我需要将数组转换为如下格式:

Array(
    [0] => array(
        [level] => 0
        [wo_number] => foo1
        [parent] => NULL
        [children] => array(
            [0] => array(
                [level] => 1
                [wo_number] => foo2
                [parent] => foo1
                [children] => array(
                    etc etc etc
                )
            )
        )
    )
)

这样我就可以对其进行 json_encode 编码,并在 ExtJS TreePanel 中使用它。

4

3 回答 3

1

使用稍微改变的功能(来自我在评论中链接的内容):

/**
 * Helper function
 * 
 * @param array  $d flat data, implementing a id/parent id (adjacency list) structure
 * @param mixed  $r root id, node to return
 * @param string $p parent id index
 * @param string $k id index
 * @param string $c children index
 * @return array
 */
function flat2nested($d, $r = 0, $p = 'parent', $k = 'id', $c = 'children') {
  $m = array();
  foreach ($d as $e) {
    isset($m[$e[$p]]) ?: $m[$e[$p]] = array();
    isset($m[$e[$k]]) ?: $m[$e[$k]] = array();
    $m[$e[$p]][] = array_merge($e, array($c => &$m[$e[$k]]));
  }

  return $m[$r]; // removed the `[0]` here
}

您可以打一个简单的电话,例如:

flat2nested($input, null, $p = 'parent', $k = 'wo_number');

虽然目前没有leaf设置索引,但似乎总是false这样,在输入数组中设置它会更容易。

演示:http ://codepad.viper-7.com/IKRLUO

flat2nested如果您对(或)的内部运作有疑问,makeRecursive请发表评论,我会扩展我的答案。

于 2012-09-19T07:34:37.307 回答
0

我有同样的问题,在 struct 的存储扩展接收到数据后,它在 javascript 下非常简单地解决了{DictDataArray: [{Id, parentId, Name}]}

appendRawData: function(data){
            var me = this;
            var rNode = me.getRootNode();
            data = (Ext.isString(data) && Ext.decode(data)) || data;
            function ParentFilter(element, index, array){
                return element.ParentId == this.filterId;
            };

            function BuildTree(list, filter){
                var tmp = list.filter(ParentFilter, filter);
                if(tmp && tmp.length)
                {
                    var node= (filter.filterId && me.getById(filter.filterId)) || rNode;
                    node && node.appendChild && node.appendChild(tmp);
                }
                for(var item in tmp){
                    BuildTree(list, {filterId: tmp[item].Id});
                    var node= me.getById(tmp[item].Id);
                    node.set('leaf', !node.hasChildNodes());
                }
            };
            data && data.DictDataResult && BuildTree(data.DictDataResult, {filterId: null});
        },

并在加载简单调用后

store.appendRawData(response)

但另一种方法是创建自己的阅读器并通过重载这个读取原始数据并根据需要转换它的函数将数据表示为 loadData

于 2013-04-25T16:26:56.077 回答
0

我修改了 Yoshi 指向我的 makeRecursive() 函数来执行以下操作:

    public function makeRecursive($d, $r = 0, $pk = 'parent', $k = 'wo_number', $c = 'children') {
            $m = array();
            foreach ($d as $e) {
                    isset($m[$e[$pk]]) ?: $m[$e[$pk]] = array();
                    isset($m[$e[$k ]]) ?: $m[$e[$k ]] = array();
                    $m[$e[$pk]][] = array_merge($e, array($c => &$m[$e[$k]]));
            }
            $final = array(
                    'wo_number'=>$r,
                    'leaf'=>false,
                    'children'=>$m[$r]
            );
            return $final;
    }

这解决了我的问题!

于 2012-09-18T21:02:02.510 回答