Свести многомерный массив потомков, но сохранить массив зависимостей - PullRequest
1 голос
/ 05 октября 2019

Я пытаюсь создать сплющенный массив результата, полученного из API. Результирующий массив выглядит следующим образом:

$arrayIhave = array(
 'element name single' => array(
   '__sort_name' => 'Name for sorting',
   'id' => '1',
 ),
 'element name single2' => array(
   '__sort_name' => 'Name for sorting',
   'id' => '2',
 ),
 'element name with nested' => array(
   '__sort_name' => 'Name for sorting',
   'sub folder name' -> array(
     '__sort_name' => 'Name for sorting',
     'id' => '3',
   ),
   'another sub folder' => array(
     '__sort_name' => 'Name for sorting',
     'id' => '4',
   )
 ),
 'element name with multi nested' => array(
   '__sort_name' => 'Name for sorting',
   'sub folder name' -> array(
     '__sort_name' => 'Name for sorting',
        'sub sub folder name' -> array(
          '__sort_name' => 'Name for sorting',
          'id' => '5',
        ),
     ),
   ),
   'another sub folder' => array(
     '__sort_name' => 'Name for sorting',
     'id' => '6',
   )
 ),
);

Конечный массив, который я пытаюсь упорядочить, имеет идентификатор каждого элемента, и ему даны зависимости в дереве. Таким образом, элемент верхнего уровня имеет id зависимости для всех своих подпапок, независимо от того, на сколько уровней ниже.

Последняя подпапка в дереве имеет зависимость только для своих детей. Дерево зависимостей не будет использовать идентификатор, так как folders не имеет этого.

Результирующий массив:

$arrayITryToHave = array(
 'element name single' => array(),
 'element name single2' => array(),
 'element name with nested' => array(
   'sub folder name',
 ),
 'element name with multi nested' => array(
   'sub folder name',
   'sub sub folder name', // Note the dependency array is flat and has all levels flatten
   'another sub folder',
 ),
 'sub folder name' => array( // Even though a subfolder, it has dependencies too
   'sub sub folder name',
 ),
);

Я пытался использовать array_walk_recursive и foreach и array_column но это не работает на нескольких уровнях. Я также пытался использовать обычные массивы foreach и &$reference, но затем мне не удалось добавить sub sub folder к уровню зависимости 1 выше и к зависимости другого уровня выше.

Код, используемый до сих пор:

function generateArray(&$array, $iterate){
      foreach($iterate as $key => $value){
        $id = $key;
        // Remove invalid elements
        if(isset($value['__sort_name'])) unset($value['__sort_name']);
        // If not present already, make an array
        if(!isset($array[$id])){
          $array[$id] = array();
        }
        array_push($array[$id], array_column($value, 'name', 'name'));
      }
    }

Как бы вы подошли к этой проблеме?

1 Ответ

0 голосов
/ 05 октября 2019

Хорошо, мне удалось решить это таким образом, если у кого-то есть лучший способ, пожалуйста, дайте мне знать:)

function generateCollapseFolder($returnArr){
      $iterator = new \RecursiveIteratorIterator(
          new \RecursiveArrayIterator($returnArr),
          \RecursiveIteratorIterator::SELF_FIRST
      );
      $filtered = array();
      $filteredLastArrayHelper = array();
      foreach ($iterator as $key => $item) {
        // Get if we are deep down
        $currentDepth = $iterator->getDepth();
        $isNested = $currentDepth > 0;
        // We only care about this field
        if($key === '__sort_name'){
          if(!isset($filtered[$item])) $filtered[$item] = array();
          // Remember last level with key to match
          $filteredLastArrayHelper[$currentDepth] = $item;
          if($isNested){
            for ($x = $currentDepth - 1; $x >= 0; $x--) {
              $insertKey = $filteredLastArrayHelper[$x];
              if($insertKey){
                array_push($filtered[$insertKey], $item);
              }
            } 
          } else {
            // Reset the array
            $filteredLastArrayHelper = array();
          }
        }
      }
      return $filtered;
}
...