C# 关于子列表性质的C Linq和滤波器
我尝试使用linq筛选子列表属性上的列表,但我无法正确地进行筛选。 例如,我有这些课程C# 关于子列表性质的C Linq和滤波器,c#,linq,list,C#,Linq,List,我尝试使用linq筛选子列表属性上的列表,但我无法正确地进行筛选。 例如,我有这些课程 public class MyClass1 { public int Id { get; set; } public List<MyClass2> MyClasses2 { get; private set; } } public class MyClass2 { public int Id { get; set; } public List<MyClass3> My
public class MyClass1
{
public int Id { get; set; }
public List<MyClass2> MyClasses2 { get; private set; }
}
public class MyClass2
{
public int Id { get; set; }
public List<MyClass3> MyClasses3 { get; private set; }
/* EDIT */
public virtual void RemoveClass3(MyClass3 elementToRemove) { ... }
}
public List<myClass2> myList2_1;
public List<myClass2> myList2_2;
public class MyClass3
{
public int Id { get; set; }
public Boolean Property1 { get; set; }
}
public List<myClass3> myList3_1;
public List<myClass3> myList3_2;
public List<myClass3> myList3_3;
最后
myClass1 1A = new MyClass1 { Id=1, MyClasses2=myList2_1 };
myClass1 1B = new MyClass1 { Id=2, MyClasses2=myList2_2 };
public List<MyClass1> list;
list.AddRange(new []{ 1A, 1B });
然后,使用此选项,我想筛选有关Property1的列表。
例如,我在true上的Property1上的筛选列表应该如下所示:
filtered_list = 1-1-1-true
我希望我足够清楚,否则我可以试着解释更多
最后,我的问题是:我想对列表应用Linq查询,以获得过滤后的列表。我试过了,在哪里。。。。我没有获得一个包含筛选子列表的列表
感谢您的帮助,并告诉我如何使用Linq筛选列表和子列表
编辑:我看到linq不可能或几乎在一步之内完成它。
因此,我考虑在dtb的帮助下,通过3个步骤实现另一个解决方案:
-筛选所有MyClass2元素的所有MyClass3列表
-筛选MyClass3列表中至少有1个元素的MyClass2
-筛选MyClass1,其中MyClasses2列表中至少有1个元素
我设法做到了第三步,但第一步我没有做到。你能再帮我一次吗
我有一个方法RemoveClass3,可以帮助我在MyClass2声明中执行第一步
var result = (from x in list
from y in x.MyClasses2
from z in y.MyClasses3
where z.Property1
group new { y, z } by x.Id into g1
select new MyClass1
{
Id = g1.Key,
MyClasses2 = (from p in g1
group p.z by p.y.Id into g2
select new MyClass2
{
Id = g2.Key,
MyClasses3 = (from r in g2
select new MyClass3
{
Id = r.Id,
Property1 = r.Property1
}).ToList()
}).ToList()
}).ToList();
递归地从列表中删除任何不需要的项可能比使用LINQ更优雅。make helper extensions:
public static class MyClassHelper
{
public static void Output(this MyClass1 item1)
{
Console.Write(item1.Id);
Console.Write("-");
foreach (var item2 in item1.MyClasses2)
{
Console.Write(item2.Id);
Console.Write("-");
foreach (var item3 in item2.MyClasses3)
{
Console.Write(item3.Id);
Console.Write("-");
Console.Write(item3.Property1);
}
}
Console.WriteLine();
}
public static IEnumerable<MyClass1> Flatten(this IEnumerable<MyClass1> list)
{
foreach (var item1 in list)
{
foreach (var item2 in item1.MyClasses2)
{
foreach (var item3 in item2.MyClasses3)
{
yield return new MyClass1
{
Id = item1.Id,
MyClasses2 = new[]
{
new MyClass2 { Id = item2.Id, MyClasses3 = new[]{item3}.ToList()}
}.ToList()
};
}
}
}
}
}
谢谢你的快速回答!我明天一早试试,然后告诉你结果。谢谢所以我尝试了一下,但并没有完全奏效:列表被很好地过滤了,但MyClasses2和MyClasses3没有。在我的例子中,我得到的是前三行,而不是第一行。但是,当我更好地了解你的目的时,我相信我会理解为什么:Any不会过滤,但只会在一个元素正常时才查看。事实上,它有点复杂:我有3个类,我打印一个表,表中有一列,按类Id和名称打印。所以我不需要像1-2-3-4那样打印,只是为了更清晰地呈现。但事实并非如此:那我就放弃了。我不知道你想要什么。我对加载。。。这个过滤器在我的应用程序中使用过很多次,我认为递归性对于这个来说太重了…嗨!对不起,我迟了答复。事实上,我想避免foreach。。。这种方法会被多次使用,我认为linq比3 foreach更适合这种方法。现在,正如你在我的第一篇文章的编辑中所看到的,我想分三个步骤来完成这件事,我首先需要两个步骤的帮助。
var result = (from x in list
from y in x.MyClasses2
from z in y.MyClasses3
where z.Property1
group new { y, z } by x.Id into g1
select new MyClass1
{
Id = g1.Key,
MyClasses2 = (from p in g1
group p.z by p.y.Id into g2
select new MyClass2
{
Id = g2.Key,
MyClasses3 = (from r in g2
select new MyClass3
{
Id = r.Id,
Property1 = r.Property1
}).ToList()
}).ToList()
}).ToList();
public static class MyClassHelper
{
public static void Output(this MyClass1 item1)
{
Console.Write(item1.Id);
Console.Write("-");
foreach (var item2 in item1.MyClasses2)
{
Console.Write(item2.Id);
Console.Write("-");
foreach (var item3 in item2.MyClasses3)
{
Console.Write(item3.Id);
Console.Write("-");
Console.Write(item3.Property1);
}
}
Console.WriteLine();
}
public static IEnumerable<MyClass1> Flatten(this IEnumerable<MyClass1> list)
{
foreach (var item1 in list)
{
foreach (var item2 in item1.MyClasses2)
{
foreach (var item3 in item2.MyClasses3)
{
yield return new MyClass1
{
Id = item1.Id,
MyClasses2 = new[]
{
new MyClass2 { Id = item2.Id, MyClasses3 = new[]{item3}.ToList()}
}.ToList()
};
}
}
}
}
}
//output all
foreach (var item1 in list.Flatten())
{
item1.Output();
}
Console.WriteLine();
//output filtered items
var filtered_list = list
.Flatten()
.Where(item1 => item1.MyClasses2
.Any(item2 => item2.MyClasses3
.Any(item3 => item3.Property1 == true)
)
)
.ToArray();
foreach (var item1 in filtered_list)
{
item1.Output();
}