Удалить один элемент из коллекции в Foreach - PullRequest
0 голосов
/ 10 сентября 2018

Было просто интересно, небезопасно ли это / плохо или просто выглядит грязно, чтобы удалить один элемент из коллекции, находясь в цикле foreach, не сохраняя его для выполнения вне цикла.Я знаю, что если вам придется продолжать итерацию, это может нарушить цикл (а в некоторых случаях просто выдать ошибку), но в этом случае вам не нужно повторять итерацию снова, потому что вы используете оператор 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 голосов
/ 11 сентября 2018

Вы не можете удалить с помощью foreach, потому что foreach использует ключевое слово yield, которое не позволяет изменять Почему? .

Ответ maccettura в порядке, но если вы заботитесь о производительности,не используйте LINQ в этом случае, потому что LINQ в основном будет перебирать весь список независимо от того, что , вы просто хотите удалить первое значение, поэтому просто используйте старый стиль - для или во время.Ваш код не подходит, потому что вы используете "==" для сравнения строк.

Ваш код может выглядеть следующим образом:

Решение 1: цикл медленнее, чемследовательно, этот подход для простоты.

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);
}
0 голосов
/ 10 сентября 2018

Вместо использования цикла foreach и наличия немного грязного / хакерского кода. Всего одна строка с помощью метода RemoveAll():

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

Скрипка здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...