【问题标题】:LINQ: Select where object does not contain items from listLINQ:选择对象不包含列表中项目的位置
【发布时间】:2011-04-12 19:04:04
【问题描述】:

我在这里为 LINQ 语法苦苦挣扎……我想我会把它扔在这里。我在其他任何地方都找不到我正在寻找的东西。

好的,说我有这个:

public class Bar
{
   public int BarId { get; set; }
}

public class Foo
{
   public List<Bar> BarList { get; set; }
}

List<Foo> fooBunch = GetABunchOfFoos(); //let's just assume I'm getting more than one
List<Foo> fooSelect = new List<Foo>;
List<Bar> filterBars = GetAFewBars(); //assume I'm getting like 2 or 3

fooSelect = (from f in fooBunch
             where !(from b in f.BarList select b.BarId).Contains(ITEM FROM filterBars.BarId)
             select f).ToList();

所以,长话短说,我想使用 LINQ 根据另一个列表中的对象过滤掉我的对象列表。我希望这是有道理的。我想我只是迷失在包含部分...我不知道该怎么写。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    一般来说,您正在寻找“Except”扩展。

    var rejectStatus = GenerateRejectStatuses();
    var fullList = GenerateFullList();
    var rejectList = fullList.Where(i => rejectStatus.Contains(i.Status));
    var filteredList = fullList.Except(rejectList);
    

    在此示例中,GenerateRegectStatuses() 应该是您希望拒绝的状态列表(或者根据您的示例更具体的术语,ID 的List&lt;int&gt;

    【讨论】:

    • 这真的很接近......诀窍是从动态状态创建拒绝列表。它更像是 i => i.Status in(list)。我可以做这样的事情吗?我猜基本上是另一个 LINQ 语句?
    • 当然,要构建rejectList,您只需要设计一种方法来获取您不想要的拒绝列表。例如:var rejectList = fullList.Where(i =&gt; rejectStatuses.Contains(i.Status)); 我将更新我的原始答案以反映这一变化。
    • 我如何在一行中做到这一点?我知道这可能是不可能的。
    【解决方案2】:

    将其转储到更具体的集合中,其中包含您不想要的 id

    var notTheseBarIds = filterBars.Select(fb => fb.BarId);
    

    然后试试这个:

    fooSelect = (from f in fooBunch
                 where !notTheseBarIds.Contains(f.BarId)
                 select f).ToList();
    

    或者这个:

    fooSelect = fooBunch.Where(f => !notTheseBarIds.Contains(f.BarId)).ToList();
    

    【讨论】:

    • 不错。我更喜欢这个答案。 +1
    • 这个答案比选中的好
    • 干净简单!不错
    • @Rarepuppers - 我花了几分钟试图理解接受的答案,然后在这里查看建议的我已经输入的内容,然后我才确定它是否有效......
    • 这应该是公认的答案。我一直在寻找了解它是如何工作的。非常感谢!
    【解决方案3】:

    我没有尝试过,所以我不保证任何东西,但是

    foreach Bar f in filterBars
    {
         search(f)
    }
    Foo search(Bar b)
    {
        fooSelect = (from f in fooBunch
                     where !(from b in f.BarList select b.BarId).Contains(b.ID)
                     select f).ToList();
    
        return fooSelect;
    }
    

    【讨论】:

    • 据我所知,b.ID 无法编译。 Contains 方法似乎失去了 b 的上下文。
    • 您使用了两个名为b 的变量,编译器可能会发现它不明确。
    【解决方案4】:

    试试这个简单的 LINQ:

    //For a file list/array
    var files = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories);
    
    //simply use Where ! x.Contains
    var notContain = files.Where(x => ! x.Contains(@"\$RECYCLE.BIN\")).ToList();
    
    //Or use Except()
    var containing = files.Where(x => x.Contains(@"\$RECYCLE.BIN\")).ToList();
        notContain = files.Except(containing).ToList();
    

    【讨论】:

      猜你喜欢
      • 2017-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多