2017-06-21 16 views
5

Poszukuję najlepszego sposobu konwersji wielu ścieżek napisów do obiektu zagnieżdżonego za pomocą javascript. Używam Lody, jeśli mogłoby to w jakikolwiek sposób pomóc.Utwórz obiekt zagnieżdżony z wielu ścieżek strunowych

mam następujące ścieżki:

/root/library/Folder 1 
/root/library/Folder 2 
/root/library/Folder 1/Document.docx 
/root/library/Folder 1/Document 2.docx 
/root/library/Folder 2/Document 3.docx 
/root/library/Document 4.docx 

i chciałbym utworzyć następującą tablicę obiektu:

var objectArray = 
    [ 
     { 
     "name": "root", "children": [ 
      { 
      "name": "library", "children": [ 
       { 
       "name": "Folder 1", "children": [ 
        { "name": "Document.docx", "children": [] }, 
        { "name": "Document 2.docx", "children": [] } 
       ] 
       }, 
       { 
       "name": "Folder 2", "children": [ 
        { "name": "Document 3.docx", "children": [] } 
       ] 
       }, 
       { 
       "name": "Document 4.docx", "children": [] 
       } 
      ] 
      } 
     ] 
     } 
    ]; 

Odpowiedz

6

Sugeruję implementację funkcji wstawiania drzewa, której argumentami jest tablica elementów podrzędnych i ścieżka. Przechodzenia dzieci według zadanego toru i wstawia nowe dzieci, w razie potrzeby, unikając duplikatach

// Insert path into directory tree structure: 
 
function insert(children = [], [head, ...tail]) { 
 
    let child = children.find(child => child.name === head); 
 
    if (!child) children.push(child = {name: head, children: []}); 
 
    if (tail.length > 0) insert(child.children, tail); 
 
    return children; 
 
} 
 

 
// Example: 
 
let paths = [ 
 
    '/root/library/Folder 1', 
 
    '/root/library/Folder 2', 
 
    '/root/library/Folder 1/Document.docx', 
 
    '/root/library/Folder 1/Document 2.docx', 
 
    '/root/library/Folder 2/Document 3.docx', 
 
    '/root/library/Document 4.docx' 
 
]; 
 

 
let objectArray = paths 
 
    .map(path => path.split('/').slice(1)) 
 
    .reduce((children, path) => insert(children, path), []); 
 

 
console.log(objectArray);

+0

Zastanawiam się, która jest szybsza, ta lub odpowiedź @ Jonasw. jakiekolwiek myśli? Dla mnie jest to o wiele bardziej czytelne. dwa razy, jeśli to możliwe. : D –

+0

@GeomanYabes to równa się moja pierwsza odpowiedź (jednak wygląda o wiele lepiej) –

+0

@GeomanYabes Ta funkcja rekursywna ściśle podąża za powstałą strukturą drzewa i wyszukuje pasujące elementy potomne w tablicy w czasie liniowym. Można to poprawić poprzez bezpośrednie odwzorowanie nazw potomków na właściwości obiektu węzła drzewa nadrzędnego i późniejsze przekształcenie w układ tablicy OP. Który przyszedłby z dodatkowym stałym kosztem, więc prawdopodobnie niepożądany, chyba że OP zajmie się wieloma ścieżkami. –

1

iteracyjne nad każdej struny i rozwiązać go do obiektu:

var glob={name:undefined,children:[]}; 

["/root/library/Folder 1","/root/library/Folder 2","/root/library/Folder 1/Document.docx","/root/library/Folder 1/Document 2.docx","/root/library/Folder 2/Document 3.docx","/root/library/Document 4.docx"] 
.forEach(function(path){ 

    path.split("/").slice(1).reduce(function(dir,sub){ 

    var children; 

    if(children=dir.children.find(el=>el.name===sub)){ 
     return children; 
    } 

    children={name:sub,children:[]}; 
    dir.children.push(children); 
    return children; 

    },glob); 

}); 

console.log(glob); 

http://jsbin.com/yusopiguci/edit?console


Ulepszona wersja:

var glob={name:undefined,children:[]}; 
var symbol="/" /* or Symbol("lookup") in modern browsers */ ; 
var lookup={[symbol]:glob}; 

["/root/library/Folder 1","/root/library/Folder 2","/root/library/Folder 1/Document.docx","/root/library/Folder 1/Document 2.docx","/root/library/Folder 2/Document 3.docx","/root/library/Document 4.docx"] 
.forEach(function(path){ 

    path.split("/").slice(1).reduce(function(dir,sub){ 
    if(!dir[sub]){ 
     let subObj={name:sub,children:[]}; 
     dir[symbol].children.push(subObj); 
     return dir[sub]={[symbol]:subObj}; 
    } 
    return dir[sub]; 
    },lookup); 

}); 

console.log(glob); 

tworzy ten sam wynik, ale to może się znacznie szybciej (do O (n) w porównaniu do O (n + n)!) http://jsbin.com/xumazinesa/edit?console

+0

'dir.children [SUB]' nic nie powrócić. Będzie szukać 'dir.children [" Folder 1 "]', itd. 'Dir.children' to tablica obiektów, a nie sam obiekt. Będziesz dodawać właściwości do obiektu tablicy, co jest wzorcem zapobiegawczym, jeśli kiedykolwiek widziałem. Twoje dane wyjściowe nie będą wyglądać tak, jak żądane dane wyjściowe PO – mhodges

+1

Wygląda na to, że teraz działa. Gdyby miał jakiś biały spisek, bym go przegłosował. –

+0

Idź, teraz wygląda dobrze. Nie jest fanem zadań w wyrażeniach warunkowych, ale działa. – mhodges

Powiązane problemy