Как построить многомерное дерево массивов из ассоциативного массива в PHP? - PullRequest
1 голос
/ 30 марта 2019

Я пытаюсь построить многомерное дерево массивов из ассоциативного массива, заменив значения строк ключей 's' и 'd' соответствующими им массивами ключей 'bandnumber', но, похоже, не могу его взломать. Я смог заставить его работать только для первого узла массива.

Например, у меня есть следующий массив:

$coiArray = array (
    array('bandnumber' => '02-BELG-2129929', 's'  =>'94-BELG-3237180', 'd' => '96-BELG-3156295' ),
    array('bandnumber' => '94-BELG-3237180', 's'  =>'88-BELG-3206112', 'd' => '88-BELG-3206173' ),
    array('bandnumber' => '88-BELG-3206112', 's'  =>'81-BELG-3238253', 'd' => '87-BELG-3008002' ),
    array('bandnumber' => '88-BELG-3206173', 's'  =>'', 'd' => '' ),
    array('bandnumber' => '96-BELG-3156295', 's'  =>'88-BELG-3206112', 'd' => '85-BELG-3049648' ),
    array('bandnumber' => '85-BELG-3049648', 's'  =>'', 'd' => '' ),
    array('bandnumber' => '81-BELG-3238253', 's'  =>'', 'd' => '' ),
    array('bandnumber' => '87-BELG-3008002', 's'  =>'', 'd' => '' ),
);

И я пытаюсь программно преобразовать вышеуказанный массив в следующее дерево многомерного массива:

$coiNestedArray = array('bandnumber' => '02-BELG-2129929',
               's' => array('bandnumber' => '94-BELG-3237180',
                     's' => array('bandnumber' => '88-BELG-3206112',
                           's' => array('bandnumber' => '81-BELG-3238253',
                                                 's' =>'',
                                                 'd' => ''
                           ),
                           'd' => array('bandnumber' => '87-BELG-3008002',
                                                 's' =>'',
                                                 'd' => ''
                           )
                     ),
                     'd' => array('bandnumber' => '88-BELG-3206173',
                           's' =>'',
                           'd' => ''
                     )
               ),
               'd' => array('bandnumber' => '96-BELG-3156295',
                     's' => array('bandnumber' => '88-BELG-3206112',
                           's' => array('bandnumber' => '81-BELG-3238253',
                                                 's' =>'',
                                                 'd' => ''
                           ),
                           'd' => array('bandnumber' => '87-BELG-3008002',
                                                 's' =>'',
                                                 'd' => ''
                           )
                     ),
                     'd' => array('bandnumber' => '85-BELG-3049648',
                           's' =>'',
                           'd' => ''
                     )
               )
        );

Это самый близкий к настоящему моменту, но он обновляет только первый узел массива:

function findKey($coiarray, $bandnumber){
    $thisCol = array_column($coiarray, 'bandnumber');
    $found_key = array_search($bandnumber, $thisCol);
    return $found_key;
}


foreach ($coiArray as $key => $value) {

    $s = '';

    $found_key = findKey($coiArray,$coiArray[$key]['s']);
    if(isset($coiArray[$found_key])){
        $s = $coiArray[$found_key];
    }

    $d = '';

    $found_key = findKey($coiArray,$coiArray[$key]['d']);
    if(isset($coiArray[$found_key])) {
        $d = $coiArray[$found_key];
    }

    $coiArray[$key] = array('bandnumber' => $coiArray[$key]['bandnumber'], 's'  => $s, 'd' => $d );

}

Я перефразирую после публикации всего дампа массива здесь, но это первый узел $coiArray, начиная с var_dump($coiArray), и вы заметите все внутренние вложенные ["s"] и Клавиши ["d"] являются строками вместо их соответствующих массивов.

[0]=>
  array(3) {
    ["bandnumber"]=>
    string(15) "02-BELG-2129929"
    ["s"]=>
    array(3) {
      ["bandnumber"]=>
      string(15) "94-BELG-3237180"
      ["s"]=>
      string(15) "88-BELG-3206112"
      ["d"]=>
      string(15) "88-BELG-3206173"
    }
    ["d"]=>
    array(3) {
      ["bandnumber"]=>
      string(15) "96-BELG-3156295"
      ["s"]=>
      string(15) "88-BELG-3206112"
      ["d"]=>
      string(15) "85-BELG-3049648"
    }
  }

Пример ниже - это первый узел из $coiNestedArray, который я создал вручную, чтобы проиллюстрировать, чего я пытаюсь достичь. Обратите внимание, что каждый ["s"] и ["d"] является массивом, полученным из $coiArray.

array(3) {
  ["bandnumber"]=>
  string(15) "02-BELG-2129929"
  ["s"]=>
  array(3) {
    ["bandnumber"]=>
    string(15) "94-BELG-3237180"
    ["s"]=>
    array(3) {
      ["bandnumber"]=>
      string(15) "88-BELG-3206112"
      ["s"]=>
      array(3) {
        ["bandnumber"]=>
        string(15) "81-BELG-3238253"
        ["s"]=>
        string(0) ""
        ["d"]=>
        string(0) ""
      }
      ["d"]=>
      array(3) {
        ["bandnumber"]=>
        string(15) "87-BELG-3008002"
        ["s"]=>
        string(0) ""
        ["d"]=>
        string(0) ""
      }
    }
    ["d"]=>
    array(3) {
      ["bandnumber"]=>
      string(15) "88-BELG-3206173"
      ["s"]=>
      string(0) ""
      ["d"]=>
      string(0) ""
    }
  }

Как мне решить эту проблему?

1 Ответ

1 голос
/ 31 марта 2019

Вам потребуется создать ассоциативный массив, снабженный номерами каналов, чтобы вы могли напрямую находить строки по номерам каналов.Затем посетите дочерние элементы и замените каждого дочернего элемента соответствующим значением в этом ассоциативном массиве по ссылке.

При желании определите, какой номер канала никогда не упоминался как дочерний: это корень.Но если вам известен корневой номер полосы или он всегда указан в первой строке ввода, вы можете пропустить этот последний шаг.Наконец, извлеките значение этого корня (при условии, что он ровно один):

// Key the rows by their bandnumber:
foreach($coiArray as $row) {
    $hash[$row["bandnumber"]] = $row;
}
foreach($hash as &$row) {
    // Replace children with the corresponding row in the hash
    foreach(["s","d"] as $prop) {
        $child = $row[$prop];
        if (!isset($hash[$child])) continue;
        $row[$prop] =& $hash[$child];
        $children[] = $child; // Keep track of non-root bandnumbers
    }
}
// Only needed when you don't know which bandnumber is the root:
$root = current(array_diff(array_keys($hash), $children, ["s","d"]));

$result = $hash[$root];
...