2017-02-09 122 views
1

我有後JSON序列化成爲這樣的一個C#對象:刪除在C#列表空節點

var tree = [{ 
Id:1, 
text: "Parent 1", 
ParentId:0 
nodes: [ 
    { 
    Id:2, 
    text: "Child 1", 
    ParentId:1 
    nodes: [ 
     { 
     Id:3 
     text: "Grandchild 1", 
     ParentId:2, 
     nodes:[] 
     }, 
     { 
     Id:4, 
     text: "Grandchild 2", 
     ParentId:2, 
     nodes: [] 
     } 
    ] 
    }, 
    { 
    Id:5 
    text: "Child 2", 
    ParentId:1, 
    nodes: [] 
    } 
] 
}, 
{ 
Id:6, 
text: "Parent 2", 
ParentId:0 
nodes: [] 
}]; 

我想刪除是空即[]從對象或只是將它們標記的所有節點爲空,所以我的最終目標看起來像

var tree = [{ 
Id:1, 
text: "Parent 1", 
ParentId:0 
nodes: [ 
    { 
    Id:2, 
    text: "Child 1", 
    ParentId:1 
    nodes: [ 
     { 
     Id:3 
     text: "Grandchild 1", 
     ParentId:2, 
     nodes:null 
     }, 
     { 
     Id:4, 
     text: "Grandchild 2", 
     ParentId:2, 
     nodes:null 
     } 
    ] 
    }, 
    { 
    Id:5 
    text: "Child 2", 
    ParentId:1, 
    nodes:null 
    } 
] 
}, 
{ 
Id:6, 
text: "Parent 2", 
ParentId:0 
nodes:null 
}]; 

名單是動態的,可以有很多branches.Thanks。 我的C#類是這個

public class Tree 
{ 
    public int Id { get; set; } 
    public string text { get; set; } 
    public int ParentId { get; set; } 
    public List<Tree> nodes { get; set; } 
} 

爲了創建樹列表對象我的功能:

var treeItems = new List<Tree>(); //Contails Flat Data No tree 
treeItems = SomeMethod(); //To populate flat Data 
treeItems.ForEach(item => item.nodes = treeItems.Where(child => child.ParentId == item.Id).ToList()); 

現在我得到的樹結構

var tree = treeItems.First(); 

我需要一些邏輯判斷,使得最好使用linq將所有的nodes = null放在所有嵌套級別中。 以便我可以使用它bootstrap-treeview數據源。

+1

剛剛成立的屬性設置爲null,也許?一個[mcve]在這裏真的會有所幫助......(我沒有看到Javascript或Bootstrap是如何與這裏真正相關的 - 這只是C#生成的JSON,對不對?) –

+2

您是否希望從列表中刪除空的項目他們是序列化的?真的需要看到對象第一個 – Wheels73

+0

請減少到一個完整的例子(完成:所有必要的人重新創建的位)。 – Richard

回答

1
var treeItems = new List<Tree>(); //Contails Flat Data No tree 
treeItems = SomeMethod(); //To populate flat Data 
treeItems.ForEach(item => item.nodes = treeItems.Where(child => child.ParentId == item.Id).Any()?treeItems.Where(child => child.ParentId == item.Id).ToList():null); 
+0

簡單而高效。按照我的要求工作。謝謝 –

0

您可以簡單地設置nodesnull

foreach (var treeItem in treeItems) 
{ 
    if (treeItem.nodes!=null && treeItem.nodes.Count==0) 
    { 
     treeItem.nodes = null;      
    } 
} 

編輯:對於遞歸這樣做是爲了分層次:

public static class ResursiveLogic 
{ 
    public static List<Tree> RemoveEmptyNodes(this List<Tree> tree) 
    { 
     if (tree==null) 
     { 
      return null; 
     } 
     if (tree.Count == 0) 
     { 
      return null; 
     } 

     foreach (var subtree in tree) 
     { 
      subtree.nodes = subtree.nodes.RemoveEmptyNodes(); 
     } 
     return tree; 
    } 
} 

說它象下面這樣:

treeItems.RemoveEmptyNodes(); 

這可能不是作爲遞歸的最佳解決方案對性能不利。你應該檢查你的JSON序列化程序是否可以通過實現自定義代碼來爲你做到這一點。

+0

正如您所看到的,我的對象可以有多個級別,此解決方案僅適用於第一級別,即子級別1級別。 –

0
class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Tree> treeItems = SomeMethod(); 

     Console.WriteLine("BEFORE");    
     Write(treeItems.First(), 0); 

     Do(treeItems.First()); 

     Console.WriteLine(); 
     Console.WriteLine("AFTER");    
     Write(treeItems.First(), 0); 

     Console.ReadKey(); 
    } 

    private static void Write(Tree t, int currentLevel) 
    { 
     string space = " ".PadLeft(currentLevel);    

     Console.WriteLine($"{space}{t.Id} : {t.text} : {t.nodes?.Count.ToString() ?? "NULL"}"); 

     if (t.nodes == null) 
      return; 

     foreach (Tree tree in t.nodes) 
     {            
      Write(tree, currentLevel + 1); 
     } 
    } 


    private static void Do(Tree t) 
    { 
     foreach (Tree tree in t.nodes) 
     { 
      Do(tree); 
     } 

     if (t.nodes.Count == 0) 
      t.nodes = null;       
    } 

    private static List<Tree> SomeMethod() 
    { 
     List<Tree> root = new List<Tree>() 
     { 
      new Tree() {Id = 1, text = "Root", ParentId = -1, nodes = new List<Tree>()} 
     }; 

     root[0].nodes.Add(new Tree { Id = 4, text = "Level2A", ParentId = 2, nodes = new List<Tree>() }); 
     root[0].nodes.Add(new Tree { Id = 5, text = "Level2B", ParentId = 2, nodes = new List<Tree>()}); 

     root[0].nodes[1].nodes.Add(new Tree { Id = 6, text = "Level3A", ParentId = 5, nodes = new List<Tree>() }); 
     root[0].nodes[1].nodes.Add(new Tree { Id = 7, text = "Level3B", ParentId = 5, nodes = new List<Tree>() }); 
     root[0].nodes[1].nodes.Add(new Tree { Id = 8, text = "Level3C", ParentId = 5, nodes = new List<Tree>() }); 

     root[0].nodes[1].nodes[1].nodes.Add(new Tree { Id = 9, text = "Level4A", ParentId = 7, nodes = new List<Tree>() }); 


     root[0].nodes[1].nodes[1].nodes[0].nodes.Add(new Tree { Id = 10, text = "Level5A", ParentId = 9, nodes = new List<Tree>() }); 
     root[0].nodes[1].nodes[1].nodes[0].nodes.Add(new Tree { Id = 11, text = "Level5b", ParentId = 9, nodes = new List<Tree>() }); 

     return root; 
    } 

    public class Tree 
    { 
     public int Id { get; set; } 
     public string text { get; set; } 
     public int ParentId { get; set; } 
     public List<Tree> nodes { get; set; } 
    } 
} 

Output

UPDATE 如果需要通過所有的列表進行迭代,不僅第一個項目使用的主要功能DO2(樹)方法。

private static void Do2(List<Tree> t) 
    { 
     foreach (Tree tree in t) 
     { 
      if (tree.nodes.Count == 0) 
       tree.nodes = null; 
      else 
       Do2(tree.nodes); 
     }    
    }