我已经尝试了一段时间来弄清楚如何让这个工作以及经过很多谷歌而无法找到类似于我的问题(也许我正在寻找错误的东西?)我决定问:
我的传入数据基本上显示了IRC服务器UUID的二叉树,即服务器的UUID及其父UUID。我想要做的是创建一个数组的树,传入的数据如下:
Parent => Child
none => 01D
01D => 01B
01B => 01F
01B => 8OS
01B => 01k
01K => 01M
我希望它在一个数组中,如:
$tree = array('01D' => array(
'01B' => array(
'01F' => array(),
'8OS' => array(),
'01k' => array('01M' => array()));
我没有同时获取所有数据,并且它不在数据库中,所以基本上我需要能够随意添加分支。
我想这样做的主要原因是服务器中的一个消失,说“01F”我知道哪些孩子是它的,并且可以通过这些。那么,在这方面我将如何绕过孩子呢?基本上在IRC环境中,处理netsplits。
我甚至不确定这是否是最好的方法,可能不是。
答案 0 :(得分:3)
输入数据采用这种格式是没有意义的:
Parent => Child
none => 01D
01D => 01B
01B => 01F
01B => 8OS
01B => 01k
01K => 01M
...因为密钥是非唯一的(例如01B
)。您应该翻转数组,使其如下所示:
$uuids = array(
'01D' => NULL,
'01B' => '01D',
'01F' => '01B',
'8OS' => '01B',
'01K' => '01B',
'01M' => '01K'
);
查找失败节点的子节点是一个简单的循环和in_array()
调用:
$failedNodes = array('01B'); // original failed node
foreach ($uuids as $child => $parent) {
if (in_array($parent, $failedNodes)) {
$failedNodes[] = $child;
}
}
var_dump($failedNodes);
输出:
array(4) {
[0]=>
string(3) "01B"
[1]=>
string(3) "01F"
[2]=>
string(3) "8OS"
[3]=>
string(3) "01k"
}
答案 1 :(得分:1)
我通常在这种情况下使用引用或对象。我在这里向您展示的是如何使用引用,模式就像很多。
//Initialize your server array
$servers = array();
//Then, each time you get a new server to add, add it to the server list if it doesn't exist
if(!isset($servers[$myname])){
$servers[$myname] = array(
'name' => 'data1',
'prop1' => 'data2',
'prop2' => 'data3',
'prop3' => 'data4',
'prop4' => 'data5',
'childrens' => array(),
);
}
//Then add your server to the children of the appropriate server
if(isset($servers[$myparent])){
$servers[$myparent]['childrens'][] = &$servers[$myname];
}
这将创建所有可能服务器的列表,并将每个条目链接到另一个条目的子项。这样,如果删除服务器,则不会丢失此子项中的数据,只会丢失引用。
如果你在哪里预约孩子,你会得到你引用的数据,var_dump,print_r ???它们都运行良好...未设置($ servers ['thatoneserver'])你仍然保留所有服务器数据,但丢失了服务器和他们孩子的链接。
Et瞧...
答案 2 :(得分:1)
我不会重建树。只需保持亲子关系。从主要原因开始,你只关心孩子们。
$nodes = array(
'01D' => array('01B'),
'01B' => array('01F', '8OS', '01k'),
// ...
);
然后,当节点失败时,您可以轻松找到子节点($nodes[$failed]
)并从那里遍历。