【问题标题】:Create and manage nested array创建和管理嵌套数组
【发布时间】:2011-12-29 16:25:30
【问题描述】:

我已经尝试了一段时间来弄清楚如何让它发挥作用,经过大量的谷歌搜索却无法找到与我类似的问题(也许我正在寻找错误的东西?)我决定问:

我收到的数据基本上显示了 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。

我什至不确定这是否是最好的方法,可能不是。

【问题讨论】:

    标签: php arrays irc


    【解决方案1】:

    传入的数据采用这种格式是没有意义的:

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

    【讨论】:

    • 我的问题也是无限遍历孩子的孩子。那么以某种方式递归调用一个函数最适合处理它吗?也就是找到lost node的children,遍历他们children的children?
    • @TheRealRoxette:是的,这几乎是教科书的递归用例。
    【解决方案2】:

    在这种情况下,我通常使用引用或对象。我将在这里向您展示的是如何使用引用,一个模式就像很多。

    //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];
    }
    

    这将创建所有可能服务器的列表,并将每个条目链接到另一个条目的子节点。这样,如果您删除服务器,您不会丢失该子项内部的数据,只会丢失引用。

    如果你在哪里 foreach 孩子,你会得到你引用的数据,var_dump,print_r???它们都工作正常... unset($servers['thatoneserver']) 您仍然保留所有服务器数据,但会丢失该服务器及其子节点的链接。

    等等……

    【讨论】:

    • 谢谢,我会记下这一点
    【解决方案3】:

    我不会重建这棵树。简单地维护父子关系。从你的主要原因来看,无论如何你只关心孩子。

    $nodes = array(
      '01D' => array('01B'),
      '01B' => array('01F', '8OS', '01k'),
      // ...
    );
    

    那么当一个节点发生故障时,你可以很容易地找到子节点($nodes[$failed])并从那里遍历。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-02
      • 1970-01-01
      • 2021-12-15
      • 1970-01-01
      • 2022-10-21
      • 2011-01-29
      • 1970-01-01
      相关资源
      最近更新 更多