Как я выхожу из Списка <строка>.ForEach цикл при использовании анонимного делегата?

В Python re.search() возвращает ТОЛЬКО первое совпадение предложения, и ничего после этого.

Вы должны попробовать re.findall(x) в своем коде.

Всегда помните, что 0-й индекс совпадения (group(0)) возвращает полную строку, которая соответствует, поэтому похоже, что есть два x, но первый фактически является просто строкой, сопоставленной целое регулярное выражение .

Когда вы использовали group(1), был возвращен только текст в первых скобках (), который оказался таким же, как и в group(0).


TL; DR

Используйте re.search() для определения только первого совпадения и используйте re.findall() для извлечения нескольких совпадений.

38
задан abatishchev 24 August 2010 в 08:31
поделиться

9 ответов

Поскольку другие отправили, Вы не можете выйти из цикла в ForEach.

Могут Вы для использования LINQ? Если так, Вы могли легко объединить TakeWhile и пользовательский метод расширения ForEach (который примерно каждый проект, кажется, имеет в эти дни).

В Вашем примере, однако, List<T>.FindIndex была бы лучшая альтернатива - но если Вы на самом деле не делаете этого, отправьте пример того, что Вы действительно хотите сделать.

40
ответ дан Jon Skeet 27 November 2019 в 03:14
поделиться

Нет никакого цикла, к которому у каждого есть доступ, от которого можно повредиться. И каждый вызов (анонимному) делегату является новым вызовом функции, таким образом, локальные переменные не помогут. Но так как C# дает Вам закрытие, можно установить флаг и затем ничего не сделать в дальнейших вызовах:

bool stop = false;
myList.ForEach((a) => {
  if (stop) {
    return;
  } else if (a.SomeCondition()) {
    stop = true;
  }
});

(Это должно быть протестировано, чтобы проверить, сгенерирована ли корректная ссылочная семантика для закрытия.)

А более усовершенствованный подход должен был бы создать Ваш собственный дополнительный метод, который позволил делегату возвращать false для остановки цикла:

static class MyExtensions {
  static void ForEachStoppable<T>(this IEnumerable<T> input, Func<T, bool> action) {
    foreach (T t in input) {
      if (!action(t)) {
        break;
      }
    }
  }
}
28
ответ дан Richard 27 November 2019 в 03:14
поделиться

Вы имеете LINQ доступный Вам? Ваша логика кажется подобной Любому:

bool any = blackList.Any(s=>inputString.Contains(s));

, который совпадает с:

bool any = blackList.Any(inputString.Contains);

, Если у Вас нет LINQ, затем это - все еще то же как:

bool any = blackList.Find(inputString.Contains) != null;

, Если Вы хотите выполнить дополнительную логику, существуют вещи, которые можно сделать (с LINQ) с TakeWhile и т.д.

15
ответ дан Marc Gravell 27 November 2019 в 03:14
поделиться

Я не думаю, что существует изящный способ сделать это при использовании метода ForEach. hacky решение состоит в том, чтобы выдать исключение.

, Что препятствует тому, чтобы Вы делали старомодный foreach?

foreach (string item in blackList)
{
    if (!inputString.Contains(item)) continue;

    result = true;
    break;
}
6
ответ дан Michael Meadows 27 November 2019 в 03:14
поделиться

Если Вы хотите цикл, используйте цикл.

Action не допускает возвращаемого значения, таким образом, нет никакого способа, которым функция ForEach могла возможно знать, что Вы хотите повредиться, за исключением выдачи исключения. Используя исключение вот излишество.

3
ответ дан Yuliy 27 November 2019 в 03:14
поделиться

Единственный способ "выйти" из цикла состоит в том, чтобы выдать исключение. Нет никакого стиля "повреждения", способ выйти из.ForEach метода как Вы был бы нормальный цикл foreach.

2
ответ дан JaredPar 27 November 2019 в 03:14
поделиться

Метод ForEach не является средним, чтобы сделать это. Если Вы хотите знать, содержит ли набор объект, необходимо использовать, Содержит метод. И если Вы хотите выполнить проверку на всех объектах в наборе, необходимо попробовать Любой метод расширения.

2
ответ дан Rune Grimstad 27 November 2019 в 03:14
поделиться
    class Program
{
    static void Main(string[] args)
    {
        List<string> blackList = new List<string>(new[] { "jaime", "jhon", "febres", "velez" });
        string inputString = "febres";
        bool result = false;
        blackList.ForEach((item) =>
                              {
                                  Console.WriteLine("Executing");
                                  if (inputString.Contains(item))
                                  {
                                      result = true;
                                      Console.WriteLine("Founded!");
                                  }
                              },
                          () => result);
        Console.WriteLine(result);
        Console.ReadLine();
    }


}
public static class MyExtensions
{
    public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action, Func<bool> breakOn)
    {
        foreach (var item in enumerable)
        {
            action(item);
            if (breakOn())
            {
                break;
            }
        }
    }
}
1
ответ дан Jaime Febres 27 November 2019 в 03:14
поделиться
bool @break = false;

blackList.ForEach(item =>
 {  
    if(!@break && inputString.Contains(item))
     { @break = true;
       result = true;
     }

    if (@break) return;
    /* ... */
 });

Примечание, которого вышеупомянутое все еще выполнит итерации через каждый объект, но возврат сразу. Конечно, этот путь, вероятно, не так хорош как нормальное foreach .

1
ответ дан Mark Cidade 27 November 2019 в 03:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: