簡體   English   中英

將扁平結構轉換為分層結構

[英]Converting flat structure to hierarchical

我需要創建能夠將平面對象轉換為遞歸對象的函數。 這是我的示例:我有平面陣列:

var flatArray = [
    {
        Description: "G",
        guid: "c8e63b35",
        parent: null,
    },
    {
        Description: "Z",
        guid: "b1113b35",
        parent: "c8e63b35",
    },
    {
        Description: "F",
        guid: "d2cc2233",
        parent: "b1113b35",
    },
    {
        Description: "L",
        guid: "a24a3b1a",
        parent: null,
    },
    {
        Description: "K",
        guid: "cd3b11caa",
        parent: "a24a3b1a",
    },      
]

結果應該是:

recursiveArray = [
    {
        Description: "G",
        guid: "c8e63b35",
        parent: null,
        Children: [
            {
                Description: "Z",
                guid: "b1113b35",
                parent: "c8e63b35",
                Children: [
                    {
                        Description: "F",
                        guid: "d2cc2233",
                        parent: "b1113b35",
                    }
                ]
            }, 
        ]
    },
    {
        Description: "L",
        guid: "a24a3b1a",
        parent: null,
        Children: [
        {
            Description: "K",
            guid: "cd3b11caa",
            parent: "a24a3b1a",
        }
    }
]

請幫我找到方法。 一個有效的算法將不勝感激,因為我在理解如何正確執行此操作方面存在問題。 在每種情況下,我都需要在遞歸結構中找到檢查元素的特定位置,並將其推送到找到的元素子數組中。 我認為這是愚蠢且低效的。 有什么方法可以快速有效地做到這一點?

編輯:遞歸數組的格式錯誤。 現在應該沒問題了。 我的數組沒有以任何方式排序。

這個很好用,很容易閱讀:

function flatToHierarchy (flat) {

    var roots = [] // things without parent

    // make them accessible by guid on this map
    var all = {}

    flat.forEach(function(item) {
      all[item.guid] = item
    })

    // connect childrens to its parent, and split roots apart
    Object.keys(all).forEach(function (guid) {
        var item = all[guid]
        if (item.parent === null) {
            roots.push(item)
        } else if (item.parent in all) {
            var p = all[item.parent]
            if (!('Children' in p)) {
                p.Children = []
            }
            p.Children.push(item)
        }
    })

    // done!
    return roots
}

這就是我將如何做到的:

 var flatArray = [{ Description: "G", guid: "c8e63b35", parent: null, }, { Description: "Z", guid: "b1113b35", parent: "c8e63b35", }, { Description: "F", guid: "d2cc2233", parent: "b1113b35", }, { Description: "L", guid: "a24a3b1a", parent: null, }, { Description: "K", guid: "cd3b11caa", parent: "a24a3b1a", }]; var recursiveArray = unflatten(flatArray); alert(JSON.stringify(recursiveArray, null, 4));
 <script> function unflatten(items) { return items.reduce(insert, { res: [], map: {} }).res; } function insert(obj, item) { var parent = item.parent; var map = obj.map; map[item.guid] = item; if (parent === null) obj.res.push(item); else { var parentItem = map[parent]; if (parentItem.hasOwnProperty("Children")) parentItem.Children.push(item); else parentItem.Children = [item]; } return obj; } </script>

當然,這僅在您的flatArray具有每個父項都出現在其子項之前的屬性時才有效。

希望有幫助。

我試圖用偽代碼編寫算法,最終得到幾乎可以工作的 JS 代碼(也許需要一些額外的驗證/檢查),但顯示了解決問題的一般方法。

//Lets separate children (nodes with a parent) from roots (nodes without a parent)
var children = flatArray.filter(function(object){
    return object.parent !== null;
});

var roots = flatArray.filter(function(object){
    return object.parent === null;
});

//And add each child to the nodes tree
children.foreach(function(child){
    recursiveAdd(roots, child);
});

//To add a children node, node tree is searched recursively for a parent
function recursiveAdd(nodes, child){
    nodes.foreach(function(parent){
        if(parent.guid === child.parent){
            parent.Children = parent.Children | [];
            parent.Children.add(child);
        } else if(parent.Children) {
            recursiveAdd(parent.Children, child);
        }
    });
}

//Temporary children array can be garbage collected
children = null;
//Resulting node tree
var recursiveArray = roots;

這個遞歸函數可能對你有好處:

 var flatArray = [{ Description: "G", guid: "c8e63b35", parent: null, Children: [] }, { Description: "Z", guid: "b1113b35", parent: "c8e63b35", Children: [] }, { Description: "F", guid: "d2cc2233", parent: "b1113b35", Children: [] }, { Description: "L", guid: "a24a3b1a", parent: null, Children: [] }, { Description: "K", guid: "cd3b11caa", parent: "a24a3b1a", Children: [] }, ]; for (var i = 0; i < flatArray.length; i++) { recursive(flatArray[i]); } function recursive(a) { for (var i = 0; i < flatArray.length; i++) { if (flatArray[i].parent == a.guid) { var b = flatArray[i]; recursive(b); a.Children.push(b); } } } console.log(flatArray)

 var flatArray = [ { Description: "G", guid: "c8e63b35", parent: null, }, { Description: "Z", guid: "b1113b35", parent: "c8e63b35", }, { Description: "F", guid: "d2cc2233", parent: "b1113b35", }, { Description: "L", guid: "a24a3b1a", parent: null, }, { Description: "K", guid: "cd3b11caa", parent: "a24a3b1a", }, ]; //for printing function htmlPrint(obj) { document.write('<pre>'+JSON.stringify(obj,null,2)+'</pre>'); }; var guids = {}; var roots = []; flatArray.forEach(function(node){ guids[node.guid] = node; //save into a hash node.Children = []; //make sure it has a children array //save it as root if it is a root if(node.parent === null){ roots.push(node);} }); flatArray.forEach(function(node){ //if it has a parent, add self to parent's children var parent = guids[node.parent]; if(parent) parent.Children.push(node); }); htmlPrint(roots);

您可以在 Angular 中使用波紋管代碼。

flatToHierarchy(flat: any[], parent: any = null, Key: string = 'id', parentKey: string = 'parentId') {
  var leafs: any = [];

  if (!parent) {
    leafs = flat.filter((x: { [x: string]: any; }) => x[parentKey] === null);
  } else {
    leafs = flat.filter((x: { [x: string]: any; }) => x[parentKey] === parent[Key]);
  }

  if (!leafs || leafs.length == 0) {
    return;
  } else {
      leafs.forEach((item: { children: any[]; }) => {
      item.children = [];
      item.children = this.flatToHierarchy(flat, item);
    });
  }
  return leafs;
}

像這樣使用

 this.flatToHierarchy(flatItems);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM