从Foreach中的集合中删除单个元素

时间:2018-09-10 18:31:35

标签: c# collections syntax

只是想知道在foreach循环中从Collection中删除单个元素而不保存它在循环外执行是否不安全/格式不好/看起来有点脏。我知道您是否必须继续迭代,它可能会中断循环(在某些情况下,只会引发错误),但是在这种情况下,您无需再次进行迭代,因为当您找到自己要使用的内容时,您使用的是break语句寻找。

示例:

List<string> strings = new List<string>() { "A", "B", "C" };
foreach(string s in strings)
{
    if (s == "B")
    {
        strings.Remove("B");
        break;
    }
}

这不好吗?我通常将其编写为向后循环,或者将stringToRemove缓存在变量中(具有明显的名称stringToRemove),但只是想知道其他人对这种感觉如何。

2 个答案:

答案 0 :(得分:3)

不是使用foreach循环,而是使用一些凌乱/ hacky的代码。使用RemoveAll()方法仅一行:

strings.RemoveAll(x => x == "B");

提琴here

答案 1 :(得分:0)

您不能用foreach删除,因为foreach使用yield关键字,不允许修改Why?

maccettura的答案还可以,但是如果您关心性能,请不要在此使用LINQ。 之所以如此,是因为LINQ基本上无论如何都将迭代整个列表,您只想删除第一个值,所以只需使用旧样式-持续一会儿即可。您的代码不好,因为您使用的是“ ==”来比较字符串。

您的代码可能如下所示:

解决方案1: for循环比foreach慢,这种方法是为了简化。

List<string> strings = new List<string>() { "A", "B", "C" };
for(int i=0;i<=strings.Count;i++)
{
    if (strings[i].Equals("B")) //don't use == to compare string in C#
    {
        strings.RemoveAt(i);
        break;
    }
}

解决方案2:,性能可能会更复杂

List<string> strings = new List<string>() { "A", "B", "C" };
int deletePosition=0; 
bool isFound=false;
foreach(string s in strings)
{
    deletePosition++;
    if (s.Equals("B")) //don't use "==" to compare string
    {
        isFound=true;
        break;
    }
}

if(deletePosition<strings.Count-- && isFound)
{
    strings.RemoveAt(deletePosition);
}