2017-10-09 56 views
-2

像問題一樣。我想將以下列表轉換爲帶有子字段的層次列表。 'parentId'可以留下。爲了清楚起見,我只是刪除它。目標是使用ramda及其不變行爲。如何使用ramda將扁平列表變成分層列表?

const x = [ 
    { 
    id: 1, 
    parentId: null, 
    name: 'Top 1' 
    }, 
    { 
    id: 2, 
    parentId: 1, 
    name: 'Middle' 
    }, 
    { 
    id: 3, 
    parentId: 2, 
    name: 'Leaf' 
    }, 
    { 
    id: 4, 
    parentId: null, 
    name: 'Top 2' 
    }, 
]; 

到這一個:

const result = [ 
    { 
     id: 1, 
     name: 'Top 1', 
     children: [ 
      { 
       id: 2, 
       name: 'Middle', 
       children: [ 
        { 
         id: 3, 
         name: 'Leaf', 
         children: [] 
        } 
       ] 
      } 
     ] 
    }, 
    { 
     id: 4, 
     name: 'Top 2', 
     children: [] 
    } 
]; 
+0

是數據排序嗎?你有嘗試過什麼嗎?什麼不行? –

+0

我不知道拉姆達是什麼,但我會推薦以下內容:遍歷原始數組,尋找具有空parentId的任何東西,並將它們作爲新數組中的基本元素,將它們標記爲「已處理」或一些東西。然後遍歷這些新元素,使用它們的id的'parentId'查找原始​​數組中的所有項目,然後將其添加到子項中。然後遞歸地爲他們的孩子做同樣的事情,等等。 – TKoL

+0

我知道如何使用可變數據結構來實現它,這實在是微不足道的。我不知道如何使用ramda和不可變的數據結構來專門實現它。 –

回答

0

正如我在Gitter回答,這似乎做到這一點:

const makeTree = items => { 
    const hierarchy = reduce(
    (index, item) => item.parentId in index 
     ? assoc(item.id, [], assoc(item.parentId, append(item.id, index[item.parentId]), index)) 
     : assoc(item.id, [], index) 
    , {}, 
    items 
) //=> E.g. {"1":[2],"2":[3],"3":[],"4":[]} 
    const index = map(head, groupBy(prop('id'), items)) //=> E.g. {"!": <item1>, "2": <item2>, ...} 
    const makeNode = id => dissoc('parentId', assoc('children', map(makeNode, hierarchy[id]), index[id])) 

    return map(makeNode, pluck('id', filter(item => item.parentId == null, items))) 
} 

它不涉及通過數據的幾個傳球,以及使用groupBy這裏看起來有點亂,但我認爲這是合理的。

也嵌套assoc s不漂亮。我可能會重構爲compose/pipe

你可以看到在行動本就Ramda REPL