我有一个C#对象,在JSON序列化之后变成这样:
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: []
}];
我想从对象中删除所有空的节点,即[],或者只是将它们标记为null,所以我的最终对象看起来像
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
}];
列表是动态的,可以有很多分支。谢谢。 我的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数据源。
答案 0 :(得分: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);
答案 1 :(得分:0)
您只需将nodes
设为null
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序列化程序是否可以通过实现自定义代码为您执行此操作。
答案 2 :(得分: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; }
}
}
<强>更新强> 如果需要迭代所有列表,不仅第一项在main函数中使用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);
}
}