C# 用Linq选择集合子集

C# 用Linq选择集合子集,c#,linq,C#,Linq,在本示例中,如何仅获取具有任何活动条的foo,并仅返回集合中的活动条 一种可能的解决方案是这样的,但它需要重新创建Foo元素: fooList .Where(f => f.Bars.Any(b => b.IsActive)) .Select(f => new Foo() { Name = f.Name, Bars = f.Bars.Where(b => b.IsActive).ToList() }); 预期

在本示例中,如何仅获取具有任何活动条的foo,并仅返回集合中的活动条

一种可能的解决方案是这样的,但它需要重新创建Foo元素:

fooList
    .Where(f => f.Bars.Any(b => b.IsActive))
    .Select(f => new Foo()
    {
        Name = f.Name,
        Bars = f.Bars.Where(b => b.IsActive).ToList()
    });
预期结果:

FooA
    Bar1 (Active)
FooC
    Bar5 (Active)
    Bar6 (Active)

如前所述,有许多简单的解决方案,但我想知道Linq是否有任何方法可以做到这一点,而不必检索所有条,然后像在内存中检索所有条一样,将非活动条放入循环中。

如果不想重新创建
Foo的
,则使用循环

foreach(var foo in fooList.Where(f => f.Bars.Any(b => b.IsActive)))
{
    foo.Bars = foo.Bars.Where(b => b.IsActive).ToList();
}

如果您想要一个从所有
Foo
中提取的活动
Bar
实例列表,但不需要知道它们来自哪个
Foo
实例,这应该适用于您:

var activeBars = fooList.SelectMany(f => f.Bars)
                        .Where(b => b.IsActive)
                     // .Distinct() /* eliminate duplicates if you want */
                        .ToList();
SelectMany
操作符将来自每个
Foo
条连接到单个序列中。
Where
操作符只过滤出活动的代码
ToList()
强制立即填充快照


这将提供一个
列表
,其中只包含
实例,其中
IsActive==true
。如果两个或多个
Foo
可能包含相同的
Bar
,并且您希望消除这些重复项,那么在
ToList()
之前添加一个
Distinct()
操作符,您可以在select子句中处理Foo对象。lambda不一定是简单的表达式,它们可以包含多个语句

var cleanedList = fooList.Where(f => f.Bars.Any(b => b.IsActive))
                         .Select(f => {
                                          f.Bars.RemoveAll(b => !b.IsActive); 
                                          return f;
                                      }
                                 );
你需要使用

将数据添加到列表中

List<Foo> employees = new List<Foo>();
Foo employee = new Foo();
employee.Name = "Emp1";
employee.Bars = new List<Bar>();
employee.Bars.Add(new Bar { Name = "Alpesh", IsActive = true });
employee.Bars.Add(new Bar { Name = "Krunal", IsActive = true });
employee.Bars.Add(new Bar { Name = "Karthik", IsActive = false });
employee.Bars.Add(new Bar { Name = "Rakesh", IsActive = true });
employees.Add(employee);
List employees=newlist();
Foo employee=new Foo();
employee.Name=“Emp1”;
employee.bar=新列表();
Add(新条{Name=“Alpesh”,IsActive=true});
Add(newbar{Name=“Krunal”,IsActive=true});
Add(新条{Name=“Karthik”,IsActive=false});
Add(新条{Name=“Rakesh”,IsActive=true});
employees.Add(employees);
仅获取活动数据

List<Foo> newList = employees.Select(m => new Foo
        {
            Name = m.Name,
            Bars = m.Bars.Where(u => u.IsActive == true).ToList()
        }).ToList();
return newList;
List newList=employees.选择(m=>newfoo
{
Name=m.Name,
Bars=m.Bars.Where(u=>u.IsActive==true).ToList()
}).ToList();
返回newList;

是的,您必须创建新的
Foo
对象-因为现有的
Foo
对象可能具有非活动的
Bar
引用。如果不是新对象,您希望解决方案实际返回什么?你真的只关心
对象吗?(如果是这样的话,那很容易。)如果你能描述你想要的结果的“形状”,那么实现应该很简单。只是想知道是否有针对这种操作系统问题的特定于linq的解决方案(总是尝试学习新的东西):)没有更多的上下文,我们真的不知道你所说的“这种问题”是什么意思。LINQ不允许一个对象同时没有任何活动的
Bar
对象,并且仍然保留其以前的信息,如果这是您所想的……您需要在最终结果中包含活动条的Foo,还是只需要一系列活动条?您可以这样使用:var ty=employees.Select(m=>new Foo){Name=m.Name,bar=m.bar.Where(u=>u.IsActive==true).ToList()}.ToList();也
List<Foo> employees = new List<Foo>();
Foo employee = new Foo();
employee.Name = "Emp1";
employee.Bars = new List<Bar>();
employee.Bars.Add(new Bar { Name = "Alpesh", IsActive = true });
employee.Bars.Add(new Bar { Name = "Krunal", IsActive = true });
employee.Bars.Add(new Bar { Name = "Karthik", IsActive = false });
employee.Bars.Add(new Bar { Name = "Rakesh", IsActive = true });
employees.Add(employee);
List<Foo> newList = employees.Select(m => new Foo
        {
            Name = m.Name,
            Bars = m.Bars.Where(u => u.IsActive == true).ToList()
        }).ToList();
return newList;