【问题标题】:Remove All from List where each line doesn't contain any item from another list从列表中删除所有,其中每行不包含另一个列表中的任何项目
【发布时间】:2013-10-22 07:26:05
【问题描述】:

对于它的价值,我花了一段时间查看下面的相关帖子,除了它在具有多个属性而不是两个独立列表的同一个列表上工作,也不涉及包含比较而不是项目的文本匹配。

How to remove all objects from List<object> where object.variable exists at least once in any other object.variable2?

我有一个名为“fruits”的满是水果的字符串列表

Apple
Orange
Banana

我还有一个名为 products 的字符串列表,其中包含一些水果(以及其他杂项信息)和一些其他产品。

ShoeFromNike
ApplePie
OrangeDrink

我需要从第二个列表中删除所有项目,其中每个单独的行不包含水果列表中列出的任何项目。

最终结果将是仅包含以下内容的产品列表:

ApplePie
OrangeDrink

我最好的迭代方法:

//this fails becaucse as I remove items the indexes change and I remove the wrong items (I do realize I could reverse this logic and if it meets the criteria ADD it to a new list and i'm sure there's a better way.)
 for (int i = 0; i < products.Count(); i++)
        {
            bool foundMatch = false;
            foreach (string fruit in fruits)
                if (products[i].Contains(fruit))
                    foundMatch = true;

            if (foundMatch == false)
                products.Remove(products[i]);
        }

我最好的 lambda 方法:

        products.RemoveAll(p => !p.Contains(fruits.Select(f=> f)));

【问题讨论】:

    标签: c# linq collections lambda iterator


    【解决方案1】:

    如果你想保持循环,你也可以做同样的事情,但将循环的顺序颠倒......

    for (int i = products.Count()- 1; i >= 0; i--)
    {
        bool foundMatch = false;
        foreach (string fruit in fruits)
            if (products[i].Contains(fruit))
                foundMatch = true;
    
        if (foundMatch == false)
            products.Remove(products[i]);
    }
    

    这可以避免在索引循环之前从列表中删除。

    【讨论】:

      【解决方案2】:

      我个人喜欢使用 .Any(),它似乎更适合我;

          products.RemoveAll(p => !fruits.Any(f => f.IndexOf(p, StringComparison.CurrentCultureIgnoreCase) >= 0));
      

      【讨论】:

      • 是的,我想有一个更好的选择,+1。可能应该阅读 products.RemoveAll(p =&gt; !fruits.Any(f =&gt; p.Contains(f))); 以符合 OP。
      • 我很确定这是行不通的,除非 == 被覆盖。
      • @Az Za 如果产品列表中的项目是 Apple Orange,这难道不是唯一的帮助吗?换句话说,它对包含没有帮助。
      • 呃……你没事。我已将其更改为不区分大小写和不区分子字符串位置。
      • 没问题。我没有使用 .Contains() 的主要原因是因为在 LINQ to Entity Framework 和 LINQ to SQL 中使用它存在一些问题;如果你是本地人,你应该没问题。
      【解决方案3】:

      这是我想出的,可能有更好的方法。

      products.RemoveAll(p => fruits.Where(f=>p.Contains(f)).Count() == 0);
      

      用英文写着,删除所有产品包含的水果名称数量为零的产品。

      (老实说,循环可能不是那么糟糕的选择,因为它将来可能会更具可读性)。

      【讨论】:

      • 感谢您的帮助!!!即使我没有使用他的索引,而是使用您的包含,这确实是任何获得胜利的答案。 (来自您对 Az Za 回答的评论)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 2016-05-18
      • 2011-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多