2015-07-06 5 views
5

Jeśli problem próbuję rozwiązać teraz kilka godzin, ale po prostu nie mogę znaleźć rozwiązania.Konwertuj pojedynczą tablicę do tablicy wielowymiarowej w php

Jeśli pojedynczy szereg ścieżek

$singleArray = array(
    '/Web', 
    '/Web/Test1', 
    '/Web/Test2', 
    '/Web/Test2/Subfolder', 
    '/Web/Test3', 
    '/Public' 
); 

Od tej tablicy Chcę stworzyć mulitdimensional tablicę, która przechowuje klucze ale umieścić podfolderów w odpowiednich folderów nadrzędnych. Później chcę pętli na nowej tablicy aby utworzyć drzewo folderów (ale nie to jest to problem)

Nowa tablica powinna wyglądać następująco:

$multiArray = array(
    '/Web'=>array(
     '/Web/Test1'=>array(), 
     '/Web/Test2'=>array(
      '/Web/Test2/Subfolder'=>array() 
    ), 
     '/Web/Test3'=>array() 
    ), 
    '/Public'=>array() 
); 
+0

nie umieścić głos, ale jest to pytanie z prośbą o kroków logicznych zaangażowany? A może po prostu prośba o napisanie kodu dla OP? – SnoApps

+0

Dobra odpowiedź da logikę i prawdopodobnie zrobi to za pomocą kodu (ponieważ ładniej jest patrzeć niż pseudokodu lub schematów blokowych) – jcuenod

+0

Nie wiem, na co ludzie narzekają. To jest uzasadnione pytanie. Odpowiedź może być w pseudokodzie, który znasz. – Andrew

Odpowiedz

5

kod poniżej uczyni tablicę chcesz. Kluczem do rozwiązania problemu jest utworzenie odwołania do tablicy w każdej iteracji.

<?php 
$singleArray = array(
    '/Web', 
    '/Web/Test1', 
    '/Web/Test2', 
    '/Web/Test2/Subfolder', 
    '/Web/Test3', 
    '/Public' 
); 

$multiArray = array(); 

foreach ($singleArray as $path) { 
    $parts  = explode('/', trim($path, '/')); 
    $section  = &$multiArray; 
    $sectionName = ''; 

    foreach ($parts as $part) { 
     $sectionName .= '/' . $part; 

     if (array_key_exists($sectionName, $section) === false) { 
      $section[$sectionName] = array(); 
     } 

     $section = &$section[$sectionName]; 
    } 
} 
+0

Dziękuję bardzo. Działa to jak urok. Chyba moim problemem jest to, że nie zrozumiałem poprawnie odnośników. Myślę, że muszę wykopać deppera w dokumentacji i tutorialach na ten temat. Ale najpierw postaram się trochę debugować kod, aby zrozumieć, co się tutaj dzieje;) – devops21212

+0

Ładne rozwiązanie, wolę funkcję rekursywną zamiast swojego wewnętrznego "foreach". – jcuenod

0

Masz to działa! Wielkie wyzwanie!

Najpierw sortuję tablicę według liczby folderów, tak aby pierwsze przetwarzane były z najmniejszą liczbą folderów (w katalogu głównym).

Następnie funkcja przechodzi przez każdy z elementów tablicy i każdego folderu w tym elemencie, porównując go z istniejącymi elementami w tablicy i, jeśli istnieje, umieszczając go wewnątrz tego elementu jako tablicę wielowymiarową.

Będzie to działać dla maksymalnie dwóch podfolderów -/root/sub1/sub2 - ale jest całkiem proste, aby dodać funkcjonalność do głębszego użytku.

Ten przykładowy kod drukuje również, przed/po tablicach:

$singleArray = array(
    '/Web', 
    '/Web/Test1', 
    '/Web/Test2', 
    '/Web/Test2/Subfolder', 
    '/Web/Test3', 
    '/Public' 
); 


echo "<pre>"; 
print_r($singleArray); 

$multiArray = array(); 


//first sort array by how many folders there are so that root folders are processed first 
usort($singleArray, function($a, $b) { 

    $a_folders = explode("/", $a); 
    $b_folders = explode("/", $b); 

    $a_num = count($a_folders); //number of folders in first 
    $b_num = count($b_folders); //number of folders in second 

    if($a_num > $b_num) return -1; 
    elseif($a_num < $b_num) return 1; 
    else return 0; 

}); 

//foreach in array 
foreach($singleArray as $item){ 

    //get names of folders 
    $folders = explode("/", $item); 

    //if the first folder exists 
    if(in_array($folders[0], $multiArray)){ 

     $key1 = array_search($folders[0], $multiArray); 

     //repeat for subfolder #1 
     if(in_array($folders[1], $multiArray[$key1])){ 

      $key2 = array_search($folders[1], $multiArray[$key1]); 

      //repeat for subfolder #2 
      if(in_array($folders[2], $multiArray[$key1][$key2])){ 

       $key3 = array_search($folders[2], $multiArray[$key1][$key2]); 

       array_push($multiArray[$key1][$key2][$key3], $item); 

      } else array_push($multiArray[$key1][$key2], $item); 

     } else array_push($multiArray[$key1], $item); 

    } else array_push($multiArray, $item); 

} 

//reverse the array so that it looks nice 
$multiArray = array_reverse($multiArray); 

print_r($multiArray); 

Wyjście to będzie:

Array 
(
    [0] => /Web 
    [1] => /Web/Test1 
    [2] => /Web/Test2 
    [3] => /Web/Test2/Subfolder 
    [4] => /Web/Test3 
    [5] => /Public 
) 
Array 
(
    [0] => /Web 
    [1] => /Public 
    [2] => /Web/Test1 
    [3] => /Web/Test2 
    [4] => /Web/Test3 
    [5] => /Web/Test2/Subfolder 
) 
+0

Dzięki za odpowiedź. Szczerze mówiąc wcześniej miałem podobne podobne rozwiązanie. Ale jak zauważyłeś: działa tylko do drugiego podfolderu. Ale spróbuję trochę użyć twojego kodu i napisać na nim tweek, żeby użyć więcej podfolderów;) – devops21212

+0

Bez zmartwień - podobała mi się próba pracy nad tym! – Ben