我的数据库吐出了这样的层次结构数组:
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中使用它。
答案 0 :(得分:1)
使用slighlty更改的功能(来自我在评论中链接的内容):
/**
* 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
)的内部运作方式有疑问,请发表评论,我会延长答案。
答案 1 :(得分: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;
}
这解决了我的问题!
答案 2 :(得分:0)
我遇到同样的问题,并且在结构{DictDataArray: [{Id, parentId, Name}]}
的商店扩展程序收到的数据之后,在javascript下解决了它非常简单
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中,该函数读取原始数据并根据需要进行转换