JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Funciones útiles para matrices en C# (y II)

Siguiendo con el post anterior de las matrices, vamos a ver ahora como emular de forma genérica la instrucción Redim Preserve de Visual Basic desde C#.

private static Array RedimPreserve(Array matriz, int nuevoTamanho)
 {
  Array m = Array.CreateInstance(matriz.GetValue(0).GetType(), nuevoTamanho);
  int longACopiar = nuevoTamanho;
  if (nuevoTamanho > matriz.Length) longACopiar = matriz.Length;
  Array.Copy(matriz, 0, m, 0, longACopiar);
  return m;
 }

Esta versión devuelve una matriz con el tamaño indicado y preservando los elementos contenidos en la matriz original. Se usa el método Copy de la clase Array para copiar de manera eficiente los elementos y evitar hacer un bucle.

Al igual que en el post anterior también podemos considerar la versión que transforma directamente la matriz que se le pase por referencia:

 private static void RedimPreserve(ref Array matriz, int nuevoTamanho)
 {
  Array m = Array.CreateInstance(matriz.GetValue(0).GetType(), nuevoTamanho);
  int longACopiar = nuevoTamanho;
  if (nuevoTamanho > matriz.Length) longACopiar = matriz.Length;
  Array.Copy(matriz, 0, m, 0, longACopiar);
  matriz = m;
 }

Siguiendo las mismas pautas de programación podemos escribir otras funciones relacionadas con matrices escritas de forma genérica, por ejemplo las siguientes:

 private static Array AddElemento(Array matriz, object Elto)
 {
  Array m = Array.CreateInstance(Elto.GetType(), matriz.Length+1);
  Array.Copy(matriz, 0, m, 0, matriz.Length);
  m.SetValue(Elto, m.GetUpperBound(0));
  return m;
 }
 
 private static Array BorraElementos(Array matriz, int[] eltos)
 {
  //Se ordenan los índices de los elementos a eliminar
  Array.Sort(eltos);
  //se quita el primero...
  Array aux = BorraElemento(matriz, eltos[0]);
  int Anterior = eltos[0]; //para evitar repeticiones de índices a eliminar
  //Ahora se recorren el resto de los elementos a eliminar...
  int Offset = 1;
  for(int i=1;i<eltos.Length;i++)
  {
   //Si el elemento no es repetido...
   if (eltos[i] > Anterior)
   {
    //...se borra el elemento correspondiente
    aux = BorraElemento(aux, eltos[i]-Offset);
    //se anota como anterior...
    Anterior = eltos[i];
    //...y se suma uno a la cantidad a restar (hay un elemento menos)
    Offset++;
   }
  }
  return aux;
 }
 
 private static Array BorraElemento(Array matriz, int indice)
 {
  //Si el índice está fuera de los límites se lanza una excepción
  if (indice > matriz.GetUpperBound(0)) throw(new System.IndexOutOfRangeException());
  //Se crea una nueva matriz del mismo tipo (el mismo que su primer elemento) y con el tamaño adecuado...
  Array m = Array.CreateInstance(matriz.GetValue(0).GetType(), matriz.Length-1);
  //...se copian los elementos de la original menos el eliminado...
  Array.Copy(matriz,0, m, 0, indice);
  Array.Copy(matriz,indice+1,m,indice,m.Length-indice);
  //... y se devuelve.
  return m;
 }

Espero que este par de textos sirvan para ilustrar el trabajo con matrices genéricas en la plataforma .NET.

José Manuel Alarcón
Banner

Agregar comentario