我有一个复合列表如下 -
List<RestApiD3Output> result = new List<RestApiD3Output>();
使用以下模型 -
public class RestApiD3Output
{
public string name { get; set; }
public int? size { get; set; }
public IList<RestApiD3Output> children { get; set; }
}
现在,我想过滤掉名称= test的所有对象及其子对象。因此,如果父节点的名称= test且子名称不是= test,我仍然需要父节点。
所以,如果我有一个数据,如 -
{
"name": "Ford",
"children": [
{
"name": "Figo",
"children": [
{ "name": "Test", "size": 3938 },
{ "name": "Test1", "size": 3938 },
{
"name": "Test2",
"children": [
{ "name": "Test-1-1", "size": 3938 },
{ "name": "Test-1-2", "size": 3938 }
]
}
]
},
{
"name": "Test",
"children": [
{ "name": "Test1", "size": 3938 },
{ "name": "Test2", "size": 3938 },
{ "name": "Test3", "size": 3938 }
]
}
]
}
所需的输出是 -
{
"name": "Ford",
"children": [
{
"name": "Figo",
"children": [
{ "name": "Test", "size": 3938 }
]
},
{
"name": "Test",
"children": [
{ "name": "Test1", "size": 3938 },
{ "name": "Test2", "size": 3938 },
{ "name": "Test3", "size": 3938 }
]
}
]
}
编辑 -
澄清一些问题。
由于父母的名字是Test,我希望拥有整个节点及其所有子节点。因此存在Test1和Test2。
如果父节点的名称不是test,但是有一个名为Test的子节点,那么我希望节点只包含名为Test的子元素。
编辑2
情景 -
答案 0 :(得分:2)
如果您在所有级别使用相同的类,则可以使用递归方法。假设班级
public class Item
{
public string name { get; set; }
public int size { get; set; }
public IList<Item> children { get; set; }
}
我们可以做到
private bool KeepIt(Item item)
{
return item.name.StartsWith("Test");
}
// This first solution removes all the nodes not having a name starting with "Test" and not
// having any children fulfilling the same condition. But, apparently this was not what the
/// OP wanted. Please, see my update.
public void PruneTree(IList<Item> items)
{
for (int i = items.Count-1; i >= 0; i--) {
PruneTree(items[i].children);
if (items[i].children.Count == 0 && !KeepIt(items[i])) {
items.RemoveAt(i);
}
}
}
用
调用它PruneTree(result);
<强>更新强>
在您的澄清之后是另一个满足以下规则的解决方案:
public void PruneTree(IList<Item> items)
{
for (int i = items.Count - 1; i >= 0; i--) {
Item item = items[i];
if (item.name != "Test") {
PruneTree(item.children);
if (item.children.Count == 0) {
items.RemoveAt(i);
}
}
}
}
在调用PruneTree之前和之后测试输出:
这是我的整个测试课程:
public static class FilteringOutObjectFromCompositeList
{
public class Item
{
public Item()
{
children = new List<Item>();
}
public string name { get; set; }
public int size { get; set; }
public IList<Item> children { get; set; }
}
private static void PruneTree(IList<Item> items)
{
for (int i = items.Count - 1; i >= 0; i--) {
Item item = items[i];
if (item.name != "Test") {
PruneTree(item.children);
if (item.children.Count == 0) {
items.RemoveAt(i);
}
}
}
}
public static void Test()
{
var root = new Item {
name = "Ford",
children = new List<Item> {
new Item {
name = "Figo",
children = new List<Item> {
new Item { name= "Test", size= 3938 },
new Item { name= "Test1", size= 3938 },
new Item {
name= "Test2",
children = new List<Item> {
new Item { name= "Test-1-1", size= 3938 },
new Item { name= "Test-1-2", size= 3938 }
}
}
}
},
new Item {
name= "Test",
children=new List<Item> {
new Item { name= "Test1", size= 3938 },
new Item { name= "Test2", size= 3938 },
new Item { name= "Test3", size= 3938 }
}
}
}
};
PrintTree(root, 0);
PruneTree(root.children);
Console.WriteLine("----------------------");
PrintTree(root, 0);
Console.ReadKey();
}
private static void PrintTree(Item item, int level)
{
PrintIndent(level);
Console.Write("name = " + item.name);
if (item.size != 0) {
PrintIndent(level);
Console.Write("size = " + item.size);
}
Console.WriteLine();
foreach (var child in item.children) {
PrintTree(child, level + 1);
}
}
private static void PrintIndent(int level)
{
Console.Write(new String(' ', 4 * level));
}
}
答案 1 :(得分:0)
你去。
var filteredResult = result.Where(x => x.name != "test" || x.children.Count(c => c.name != "test") > 0 );
选择父名称不是&#34; test&#34;的行。或者任何一个孩子都没有&#34;测试&#34;