Цикл Foreach, определите, какая последняя итерация цикла - PullRequest
202 голосов
/ 19 сентября 2011

У меня есть цикл foreach, и мне нужно выполнить некоторую логику, когда последний элемент выбран из List, например ::

 foreach (Item result in Model.Results)
 {
      //if current result is the last item in Model.Results
      //then do something in the code
 }

Могу ли я узнать, какой цикл является последним без использования цикла и счетчиков?

Ответы [ 25 ]

0 голосов
/ 04 апреля 2017

Еще один способ, который я не видел опубликованным, - это использовать Очередь.Это аналог способа реализации метода SkipLast () без итерации больше, чем необходимо.Этот способ также позволит вам сделать это с любым количеством последних элементов.

public static void ForEachAndKnowIfLast<T>(
    this IEnumerable<T> source,
    Action<T, bool> a,
    int numLastItems = 1)
{
    int bufferMax = numLastItems + 1;
    var buffer = new Queue<T>(bufferMax);
    foreach (T x in source)
    {
        buffer.Enqueue(x);
        if (buffer.Count < bufferMax)
            continue; //Until the buffer is full, just add to it.
        a(buffer.Dequeue(), false);
    }
    foreach (T item in buffer)
        a(item, true);
}

Чтобы позвонить, вы должны сделать следующее:

Model.Results.ForEachAndKnowIfLast(
    (result, isLast) =>
    {
        //your logic goes here, using isLast to do things differently for last item(s).
    });
0 голосов
/ 24 февраля 2017

Мы можем проверить последний элемент в цикле.

foreach (Item result in Model.Results)
{
    if (result==Model.Results.Last())
    {
        // do something different with the last item
    }
}
0 голосов
/ 27 апреля 2016
foreach (DataRow drow in ds.Tables[0].Rows)
            {
                cnt_sl1 = "<div class='col-md-6'><div class='Slider-img'>" +
                          "<div class='row'><img src='" + drow["images_path"].ToString() + "' alt='' />" +
                          "</div></div></div>";
                cnt_sl2 = "<div class='col-md-6'><div class='Slider-details'>" +
                          "<p>" + drow["situation_details"].ToString() + "</p>" +
                          "</div></div>";
                if (i == 0)
                {
                    lblSituationName.Text = drow["situation"].ToString();
                }
                if (drow["images_position"].ToString() == "0")
                {
                    content += "<div class='item'>" + cnt_sl1 + cnt_sl2 + "</div>";
                    cnt_sl1 = "";
                    cnt_sl2 = "";
                }
                else if (drow["images_position"].ToString() == "1")
                {
                    content += "<div class='item'>" + cnt_sl2 + cnt_sl1 + "</div>";
                    cnt_sl1 = "";
                    cnt_sl2 = "";
                }
                i++;
            }
0 голосов
/ 20 января 2015

Джон Скит недавно создал тип SmartEnumerable<T>, чтобы решить эту проблему. Вы можете увидеть его реализацию здесь:

http://codeblog.jonskeet.uk/2007/07/27/smart-enumerations/

Для скачивания: http://www.yoda.arachsys.com/csharp/miscutil/

0 голосов
/ 07 апреля 2016

Чтобы сделать что-то дополнительное для каждого элемента, кроме последнего, можно использовать подход на основе функций.

delegate void DInner ();

....
    Dinner inner=delegate 
    { 
        inner=delegate 
        { 
            // do something additional
        } 
    }
    foreach (DataGridViewRow dgr in product_list.Rows)
    {
        inner()
        //do something
    }
}

Этот подход имеет очевидные недостатки: меньшая ясность кода для более сложных случаев. Вызов делегатов может быть не очень эффективным. Устранение неполадок может быть не совсем простым. Яркая сторона - кодирование это весело!

Сказав это, я бы предложил использовать обычные циклы for в тривиальных случаях, если вы знаете, что счет вашей коллекции не слишком медленный.

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