sábado, 26 de marzo de 2016

Pregunta C# (12 de 20): ¿Cómo Obtener el Índice de la Iteración Actual en un Ciclo foreach?

Índice

1. Introducción
2. Palabras Clave
3. Contexto
3.1 Colección
3.2 Ejemplos sobre colecciones comunes
3.2.1 Stack<T>
3.2.2 Queue<T>
3.2.3 List<T>
3.2.4 Dictionary<TKey, TValue>
4. Obtención del Índice en la Iteración de un Ciclo foreach
5. Recursos
6. Conclusiones
7. Literatura & Enlaces

1. Introducción

Esta pregunta puede resultar inquietante para aquellos programadores que en alguna oportunidad se han visto ante el requerimiento de iteración de elementos de una estructura datos -dígase un diccionario, una lista, una lista como arreglo-, que demanda conocer el índice de la iteración actual en un ciclo foreach. A continuación se demuestra cómo es posible resolver esta pregunta mostrando varios ejemplos con diferentes tipos de colecciones: la iteración de los elementos de una colección puede requerir un método diferente de cálculo u obtención del índice; no existe un método único para todos los tipos de colecciones.

2. Palabras Clave

  • Ciclo
  • Colección
  • Diccionario
  • Estructura de dato
  • Índice
  • Iteración

3. Contexto

3.1 Colección

Una colección es una estructura de datos especializada para el almacenamiento y recuperación de datos. Existen diferentes tipos de colecciones; como:
  • Pilas
  • Colas
  • Listas
  • Diccionarios
Cada una de estas colecciones permite almacenar y recuperar datos usando diferentes algoritmos especializados que pueden resultar relativamente eficientes dependiendo del problema que se desee resolver.

Respecto al lenguaje de programación C#, éste cuenta con varias clases especializadas para representar las colecciones antes mencionadas; por ejemplo:
  • Stack<T>
  • Queue<T>
  • List<T>
  • Dictionary<TKey, TValue>

3.2 Ejemplos sobre colecciones comunes

3.2.1 Stack<T>

En el namespace System.Collections.Generic se halla la clase genérica Stack<T> que representa una estructura LIFO (Last-In-First-Out) de tamaño variable ("Stack(T) Class", 2016).

Un ejemplo práctico y simple de esta clase puede ser:

Archivo C# UsoStack.cs [Enlace alternativo][Enlace alternativo]:

Compilación:

csc /t:exe UsoStack.cs


Ejecución assembly:

.\UsoStack.exe


Demostración ejecución assembly (ideone.com): http://ideone.com/vDasn5


Demostración ejecución assembly (local): 
Ejecución assembly UsoStack.exe
Figura 1. Ejecución assembly UsoStack.exe.

3.2.2 Queue<T>

La clase Queue<T> ("Queue(T) Class", 2016) representa una estructura FIFO (First-In-First-Out), es decir el primer elemento de dato que ingresa a la estructura es el primero en salir de ella.

Compilación:

csc /t:exe UsoQueue.cs

Ejecución assembly:

.\UsoQueue.exe

Demostración ejecución assembly (ideone.com): http://ideone.com/0r6A6W


Demostración ejecución assembly (local): 
Ejecución assembly UsoQueue.exe
Figura 2. Ejecución assembly UsoQueue.exe.

3.2.3 List<T>

La clase genérica List<T> representa una lista de objetos indexados. Esta clase contiene definiciones para la búsqueda, ordenamiento y manipulación de objetos. Se halla definida en el namespace System.Collections.Generic.

Compilación:

csc /t:exe UsoList.cs

Ejecución assembly

.\UsoList.exe

Demostración ejecución assembly (ideone.com): http://ideone.com/rDHHdF


Demostración ejecución assembly (local): 
Ejecución assembly UsoList.exe
Figura 3. Ejecución assembly UsoList.exe.

2.3.4 Dictionary<TKey, TValue>

Con la clase Dictionary<TKey, TValue> ("Dictionary(TKey, TValue) Class" 2016), se representa la estructura de datos basada en llave-valor.

Compilación:

csc /t:exe UsoDictionary.cs


Ejecución assembly:

.\UsoDictionary.exe

Demostración ejecución assembly (ideone.com): http://ideone.com/SBdKwY


Demostración ejecución assembly (local): 
Ejecución assembly UsoDictionary.exe
Figura 4. Ejecución assembly UsoDictionary.exe.

4. Obtención del Índice en la Iteración de un Ciclo foreach

En los ejemplos de las secciones 3.2.1-4 se mostró cómo iterar los elementos (datos) insertados en las estructuras de datos Stack<T>, Queue<T>, List<T> y Dictionary<TKey, TValue>. Sin embargo, aún no se conoce una técnica para obtener el índice actual de la iteración usando un ciclo foreach para los diferentes tipos de colecciones.

A continuación se presenta un ejemplo en donde se implementa la técnica de obtención del índice de iteración de los elementos de una colección.

Para obtener el índice en la iteración de un objeto Dictionary<TKey, TValue> se utiliza una variable auxiliar a modo de índice: como la declarada en la línea 12; luego en el ciclo foreach de las líneas 24-26 se incrementa este índice a medida que se recorren los elementos que integran el diccionario.


Ahora cuando se trata de un objeto List<T> se usa el método IndexOf<T> ("List(T).IndexOf Method", 2016) (línea 41) para obtener el índice asociado al elemento actual de la iteración. Una versión análoga de este método se utiliza para un objeto de la colección ArrayList ("ArrayList Class", 2016): IndexOf(Object) ("ArrayList.IndexOf Method", 2016) (línea 58).


Compilación:

csc /t:exe IndiceIteracionForeach.cs

Ejecución assembly:

.\IndiceIteracionForeach.exe

Demostración ejecución assembly (ideone.com): http://ideone.com/4JuDu4

Demostración ejecución assembly (local): 
Ejecución assembly IndiceIteracionForeach.exe
Figura 5. Ejecución assembly IndiceIteracionForeach.exe.

5. Recursos

Este es el vídeo en donde el equipo de expertos (Gerry O'Brein y Paul Pardi) de MVA responden y explican esta pregunta:

6. Conclusiones

Se demostró cómo es posible obtener el índice de la iteración de diferentes tipos de colecciones: List<T>, Dictionary<TKey, TValue> y ArrayList. Se comprendió que existen diferentes técnicas para la obtención de este índice dependiendo de la colección que se esté tratando.

En la próxima C# se explica el proceso de obtención de la dirección IP asociada al sistema.

7. Literatura & Enlaces

Top C# Questions Answered | Microsoft Virtual Academy (2016, marzo 26). Recuperado desde: https://mva.microsoft.com/en-US/training-courses/twenty-c-questions-answered-8298?l=ivBolUYy_3604984382
Stack(T) Class (System.Collections.Generic) (2016, marzo 26). Recuperado desde: https://msdn.microsoft.com/en-us/library/3278tedw.aspx
Queue(T) Class (System.Collections.Generic) (2016, marzo 26). Recuperado desde: https://msdn.microsoft.com/en-us/library/7977ey2c.aspx
List(T) Class (System.Collections.Generic) (2016, marzo 26). Recuperado desde: https://msdn.microsoft.com/en-us/library/6sh2ey19.aspx
Dictionary(TKey, TValue) Class (System.Collections.Generic) (2016, marzo 26). Recuperado desde: https://msdn.microsoft.com/en-us/library/xfhwa508.aspx
List(T).IndexOf Method (T) (System.Collections.Generic) (2016, marzo 26). Recuperado desde: https://msdn.microsoft.com/en-us/library/e4w08k17.aspx
ArrayList Class (System.Collections) (2016, marzo 26). Recuperado desde: https://msdn.microsoft.com/en-us/library/system.collections.arraylist(v=VS.100).aspx
ArrayList.IndexOf Method (Object) (System.Collections) (2016, marzo 26). Recuperado desde: https://msdn.microsoft.com/en-us/library/7w3e62a8(v=vs.100).aspx


V

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.