Создать и управлять вложенным массивом - PullRequest
1 голос
/ 29 декабря 2011

Я некоторое время пытался выяснить, как заставить это работать, и после большого количества Google и не в состоянии найти проблему, подобную моей (возможно я ищу неправильную вещь?), Я решилспросить:

У меня есть входящие данные, которые по существу показывают двоичное дерево UUID-ов IRC-сервера, то есть 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.

Я даже не уверен, что это лучший способ сделать это, вероятно, нет.

Ответы [ 3 ]

3 голосов
/ 29 декабря 2011

Не имеет смысла, чтобы входящие данные были в следующем формате:

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 голос
/ 29 декабря 2011

Я бы не стал перестраивать дерево.Просто поддерживайте отношения родитель-ребенок.По вашей основной причине вы все равно заботитесь только о детях.

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

Затем, когда узел выходит из строя, вы можете легко найти детей ($nodes[$failed]) и пройти оттуда.

1 голос
/ 29 декабря 2011

Ну, я обычно использую ссылки или объекты в этом случае. Здесь я покажу вам, как использовать ссылки, а шаблон похож на многое.

//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 ??? Все они работают нормально ... unset ($ серверы ['thatoneserver']) вы все еще сохраняете все свои серверные данные, но теряете этот сервер и ссылки на своих детей.

Et voila ...

...