Encontrando a última iteração de um loop

Por padrão, no C#, em um loop como o foreach não existe um indicador que o item atual é o último da lista. Por este motivo, caso seja necessário realizar alguma ação que o envolva temos que realizar uma verificação de forma manual.

Soluções

1 – Nome do método no exemplo: IdentifyLastItem_UsingGetLast
Usando GetLast() fora do loop identificamos o último elemento, dentro do loop comparamos este com o item atual usando algum atributo disponivel.

2 – Nome do método no exemplo: IdentifyLastItem_UsingGetLastCompareFullObject
Usando GetLast(), igual a solução 1, mas usando serialização do objeto para comparar todos os atributos.

3 – Nome do método no exemplo: IdentifyLastItem_UsingCountControl
Usando um contador para realizar o controle das iterações.

4 – Nome do método no exemplo: IdentifyLastItem_UsingWhileLoop
Usando o WhileLoop temos acesso aos métodos ‘MoveNext()’ e ‘Current’; desta maneira podemos identificar o último elemento quando ‘MoveNext()’ retorna false.

Exemplo: Main Class

using System;
using System.Collections.Generic;

namespace LastIterationLoop
{
    class Program
    {
        static void Main(string[] args)
        {
            var loopOptions = new ForLoopClass();
            Console.WriteLine("Call IdentifyLastItem_UsingGetLast");
            loopOptions.IdentifyLastItem_UsingGetLast(GenerateList());
            Console.WriteLine();
            Console.WriteLine("Call IdentifyLastItem_UsingGetLastCompareFullObject");
            loopOptions.IdentifyLastItem_UsingGetLastCompareFullObject(GenerateList());
            Console.WriteLine();
            Console.WriteLine("Call IdentifyLastItem_UsingCountControl");
            loopOptions.IdentifyLastItem_UsingCountControl(GenerateList());
            Console.WriteLine();
            Console.WriteLine("Call IdentifyLastItem_UsingDoWhile");
            loopOptions.IdentifyLastItem_UsingWhileLoop(GenerateList());
        }

        public static List<SampleClass> GenerateList()
        {
            var myList = new List<SampleClass>();
            myList.Add(new SampleClass { SampleId = 4, SampleName = "Name Four" });
            myList.Add(new SampleClass { SampleId = 2, SampleName = "Name Two"});
            myList.Add(new SampleClass { SampleId = 1, SampleName = "Name One" });
            myList.Add(new SampleClass { SampleId = 5, SampleName = "Name Five"});
            myList.Add(new SampleClass { SampleId = 3, SampleName = "Name Tree" }); // => last add item.
            return myList;
        }
    }
}

Exemplo: LastIterationLoop class

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;

namespace LastIterationLoop
{
    class ForLoopClass
    {

        /// <summary>
        /// Get last item and use a Key to check if the current element on the list is the last one.
        /// NOTE: this solution does not work if you can have duplicated values.
        /// </summary>
        public void IdentifyLastItem_UsingGetLast(List<SampleClass> myList)
        {
            var lastItem = myList.Last();
            foreach (var item in myList)
            {
                if (lastItem.SampleId == item.SampleId)
                {
                    Console.WriteLine("LAST ITEM " + item);
                }
                else
                {
                    Console.WriteLine("NOT LAST " + item);
                }
            }
        }

        /// <summary>
        /// Get last item and use the complete object serialized to find the last.
        /// NOTE: this solution does not work if you can have duplicated values.
        /// </summary>
        public void IdentifyLastItem_UsingGetLastCompareFullObject(List<SampleClass> myList)
        {
            var lastItem = myList.Last();
            foreach (var item in myList)
            {
                if (JsonConvert.SerializeObject(lastItem) == JsonConvert.SerializeObject(item))
                {
                    Console.WriteLine("LAST ITEM " + item);
                }
                else
                {
                    Console.WriteLine("NOT LAST " + item);
                }
            }
        }

        public void IdentifyLastItem_UsingCountControl(List<SampleClass> myList)
        {
            var listSize = myList.Count;
            int i = 0;
            foreach (var item in myList)
            {
                if (++i == listSize)
                {
                    Console.WriteLine("LAST ITEM " + item);
                }
                else
                {
                    Console.WriteLine("NOT LAST " + item);
                }
            }
        }

        public void IdentifyLastItem_UsingWhileLoop(List<SampleClass> myList)
        {
            var enumerator = myList.GetEnumerator();
            var isLast = !enumerator.MoveNext();
            SampleClass current;
            while (!isLast)
            {
                current = enumerator.Current;
                isLast = !enumerator.MoveNext();
                if (isLast)
                {
                    Console.WriteLine("LAST ITEM " + current);
                }
                else
                {
                    Console.WriteLine("NOT LAST " + current);
                }
            }
        }
    }

    public class SampleClass
    {
        public int SampleId { get; set; }
        public string SampleName { get; set; }

        public override string ToString()
        {
            return $"Sample id = {this.SampleId} and name = {this.SampleName}";
        }
    }
}

Qualquer dúvida ou dicas, entre em contato: leandrolt@gmail.com

Principais referências

– https://stackoverflow.com/questions/7476174/foreach-loop-determine-which-is-the-last-iteration-of-the-loop
– https://stackoverflow.com/questions/10454519/best-way-to-compare-two-complex-objects

Leave a Reply

Your email address will not be published. Required fields are marked *