4

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

如何从 List<object> 中删除所有对象,其中 object.variable 在任何其他 object.variable2 中至少存在一次?

我有一个完整的水果字符串列表,称为“水果”

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)));
4

3 回答 3

3

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

    products.RemoveAll(p => !fruits.Any(f => f.IndexOf(p, StringComparison.CurrentCultureIgnoreCase) >= 0));
于 2013-10-14T17:18:34.193 回答
3

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

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

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

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

于 2013-10-14T17:11:33.503 回答
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]);
}

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

于 2013-10-14T17:55:54.083 回答