La instrucción Select…Case en Visual Basic

La instrucción Select…Case de Visual Basic tiene un funcionamiento similar al Switch…Case de C: nos permite evaluar el valor de una variable y ejecutar un determinado código según su valor, sin tener que acabar recurriendo a un enorme árbol de estructuras if/else anidadas. La variable se evaluará contra una serie de expresiones por orden descendente, parando en cuanto una de las evaluaciones sea verdadera.

Su sintaxis sería la siguiente:

SELECT mivariable
  CASE expresión1
   'código
  CASE expresión2
    'otro código
  CASE ELSE
    'Código por defecto
END SELECT

La variable mivariable del ejemplo sería la que vamos a evaluar. Puede ser una variable de los siguientes tipos: Boolean, Byte, Char, Date, Double, Decimal, Integer, Long, Object, SByte, Short, Single, String, UInteger, ULong, y UShort.

Tanto expresión1, como expresión2 y demás expresiones que queramos usar será valores o conjuntos de valores numéricos o de texto contra los que se evaluará mivariable. Puede responder a tres formas: un valor solo, una comparación con la sintaxis IS seguido de un operador de comparación (mayor, menor, igual, distinto) o un conjunto de valores, que puede mostrarse de dos formas: un grupo de valores separados por comas o un rango del que daremos el valor inicial y el final unidos por un TO.

Finalmente tenemos el CASE ELSE, esto es opcional y es un código que se ejecutará si el valor de mivariable no ha dado true en ninguna de sus evaluaciones.

Veamos una serie de ejemplos. Primero, veamos un código que asigna un valor de color de fondo a un grupo de usuarios:

SELECT Grupo
  CASE "Dirección"
    colorfondo="verde"
  CASE "Producción"
    colorfondo="gris"
  CASE ELSE
    colorfondo="rojo"
END SELECT

Segundo ejemplo, un código que asigna un grupo poblacional según la edad, evaluando por rangos:

SELECT Edad
  CASE 0 to 14
    grupo="Infantil"
  CASE 15 to 20
    grupo="juvenil"
  CASE 20 to 70
    grupo="adulto"
  CASE ELSE
    grupo="anciano"
END SELECT

Tercer ejemplo, en este caso con grupos de valores por comas. Evaluamos el último número de un código y marcamos si es par o impar (sí, ya se que es más fácil hacerlo con una operación de módulo, pero esto es un simple ejemplo teórico):

SELECT Numero
  CASE 1,3,5,7,9
    impar=True 
  CASE ELSE
    impar=False
END SELECT

Y vamos a cerrar con el cuarto ejemplo, usando una expresión aritmética para la evaluación, en este caso para los pesos de una competición de lucha:

SELECT Peso
  CASE IS < 48
    categoria="minimosca" 
  CASE IS < 51
    categoria="mosca" 
  CASE IS < 54
    categoria="gallo" 
  CASE IS < 57
    categoria="pluma" 
  CASE IS < 60
    categoria="ligero"
  CASE IS < 64
    categoria="superligero" 
  CASE IS < 69
    categoria="wélter" 
  CASE IS < 75
    categoria="mediano" 
  CASE IS < 81
    categoria="semipesado" 
  CASE IS = 91
    categoria="superpesado" 
END SELECT
Anuncios

Implementar un árbol de datos genérico en VB.NET

Curiosamente Visual Basic .NET no incluye una clase de tipo árbol genérica, cosa que descubrí en mi último trabajo, donde me vi obligado a definir e implementar un árbol genérico con diversos métodos, incluyendo uno de búsqueda recursivo (que no incluiré en el ejemplo porque se basaba en los índices de la base de datos, por lo que no sería un método genérico), y que finalmente quedó a medio hacer por finalizarse mi periodo en la empresa.

El árbol genético en cuestión requiere de dos clases: una clase árbol y una clase nodo. La idea es que la clase nodo tenga una colección de otros nodos dentro (sus hijos), para crear la estructura de árbol. También tienen un método que dice si el árbol está vacío y si un nodo es una “hoja” (es decir, si carece de hijos). El método de búsqueda ya depende del tipo de árbol que quieras construir y de por qué propiedad quieras buscar, pero hay algoritmos generales por toda la red. Aquí os dejo el código de las dos clases:

Public Class Tree(Of T)
 Private m_Root As TreeNode(Of T) = Nothing
 <Description("El nodo raíz del árbol."), _
 Category("Data")> _
 Public Property Root() As TreeNode(Of T)
 Get
 Return m_Root
 End Get
 Set(ByVal value As TreeNode(Of T))
 m_Root = value
 End Set
 End Property

Public Sub Vaciar()
 m_Root = Nothing
 End Sub

Public Function IsEmpty() As Boolean
 If(Not m_Root Is Nothing)
 Return true
 End If
 Return false
 End Function

Public Function MakeRoot(ByVal node_item As T) As TreeNode(Of T)
 m_Root = New TreeNode(Of T)(node_item)
 Return m_Root
 End Function

Public Overrides Function ToString() As String
 Return m_Root.ToString()
 End Function
 End Class

Public Class TreeNode(Of T)
 Public NodeObject As T
 Public Children As New List(Of TreeNode(Of T))

Public Sub New(ByVal node_object As T)
 NodeObject = node_object
 End Sub

Public Function AddChild(ByVal node_item As T) As TreeNode(Of T)
 Dim child_node As New TreeNode(Of T)(node_item)
 Children.Add(child_node)
 Return child_node
 End Function

Public Shadows Function ToString(Optional ByVal indent As Integer = 0) As String
 Dim texto As String
 texto = New String(" "c, indent) & NodeObject.ToString & vbCrLf

For Each child As TreeNode(Of T) In Children
 texto &= child.ToString(indent + 3)
 Next child

Return texto
 End Function

Public Function IsEmpty() As Boolean
 If(Not Children Is Nothing)
 Return false
 End If
 Return true
 End Function

End Class

En fin, espero que este texto os sea de ayuda, suerte con la implementación de la búsqueda, que es lo más complejo, pero un árbol perfectamente equilibrado es una forma de optimizar tu programa y ahorrar recursos en las búsquedas.