Eventos

[C#] ¿Cómo obtener el índice de la iteración actual de un bucle foreach?


Con este post quiero demostrar 5 casos en los cuales nos podemos encontrar al momento de intentar conocer en que índice nos encontramos cuando usamos un bucle foreach. Para ello definiremos primero una clase, una estructura, un par de variables y un par de métodos.
    public class Usuario
    {
        public string Nombre { get; set; }

        public int Edad { get; set; }

        public DateTime FechaNacimiento { get; set; }

        public static List<Usuario> Listar() 
        {
            return new List<Usuario>
            {
                new Usuario { Nombre = "Atom", FechaNacimiento = DateTime.Now.AddYears(-12) },
                new Usuario { Nombre = "Bolt", FechaNacimiento = DateTime.Now.AddYears(-15) },
                new Usuario { Nombre = "Carmen", FechaNacimiento = DateTime.Now.AddYears(-18) },
                new Usuario { Nombre = "Phineas", FechaNacimiento = DateTime.Now.AddYears(-21) },
                new Usuario { Nombre = "Lawliet", FechaNacimiento = DateTime.Now.AddYears(-24) },
            };
        }
    }

    public struct Cliente
    {
        public string Nombre { get; set; }

        public int Edad { get; set; }

        public DateTime FechaNacimiento { get; set; }

        public static List<Cliente> Listar()
        {
            return new List<Cliente>
            {
                new Cliente { Nombre = "Atom", FechaNacimiento = DateTime.Now.AddYears(-12) },
                new Cliente { Nombre = "Bolt", FechaNacimiento = DateTime.Now.AddYears(-15) },
                new Cliente { Nombre = "Carmen", FechaNacimiento = DateTime.Now.AddYears(-18) },
                new Cliente { Nombre = "Phineas", FechaNacimiento = DateTime.Now.AddYears(-21) },
                new Cliente { Nombre = "Lawliet", FechaNacimiento = DateTime.Now.AddYears(-24) },
            };
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var usuarios = Usuario.Listar();
            var clientes = Cliente.Listar();

            //...
        }

        static Usuario CalcularEdad(Usuario usuario) 
        {
            usuario.Edad = (int)((DateTime.Now - usuario.FechaNacimiento).TotalDays / 365);
            return usuario;
        }

        static Cliente CalcularEdad(Cliente cliente)
        {
            cliente.Edad = (int)((DateTime.Now - cliente.FechaNacimiento).TotalDays / 365);
            return cliente;
        }
    }

1. USANDO UN CONTADOR

Es la forma más sencilla de hacer esto y es tan útil en el momento que usamos un List<T> como en el momento en que usamos un Dictionary<TKey, TValue>.
            int c = 0;
            foreach (var usuario in usuarios)
            {
                Console.WriteLine(c);
                c++;
            }

2. USANDO SYSTEM.LINQ EN CLASS

Ahora filtremos la lista usando las extensiones que hay en el namespace de System.Linq y usemos List<T>.IndexOf(T item).

            foreach (var usuario in usuarios.Where(x => x.Nombre.ToLower().Contains("a")))
                Console.WriteLine(usuarios.IndexOf(usuario));

3. USANDO SYSTEM.LINQ Y UNA FUNCION EN CLASS

            foreach (var usuario in usuarios.Where(x => x.Nombre.ToLower().Contains("a")))
            {
                var usuarioProcesado = CalcularEdad(usuario);
                Console.WriteLine(usuarios.IndexOf(usuarioProcesado) + " - " + usuarioProcesado.Edad);
            }

4. USANDO SYSTEM.LINQ EN STRUCT

            foreach (var cliente in clientes.Where(x => x.Nombre.ToLower().Contains("a")))
                Console.WriteLine(clientes.IndexOf(cliente))

5. USANDO SYSTEM.LINQ Y UNA FUNCION EN STRUCT

En los últimos ejemplos no han aparecido problemas, ha sido muy sencillo. Pero con este caso os quiero hacer recordar del particular comportamiento de un struct cuando es pasado como argumento y del cual tenemos que tener mucho cuidado.
            foreach (var cliente in clientes.Where(x => x.Nombre.ToLower().Contains("a")))
            {
                var clienteProcesado = CalcularEdad(cliente);
                Console.WriteLine(clientes.IndexOf(clienteProcesado) + " - " + clienteProcesado.Edad);
            }

CodePlex

Código fuente disponible en: CSharp -> ForeachIterationIndex

No hay comentarios.:

Publicar un comentario

Epicalsoft — Superheroic Software Development Blog Designed by Templateism.com Copyright © 2014

Con tecnología de Blogger.