Ordenando por resoluciones

Esto es una tontería del tipo tonterida, pero me ha llevado un ratito escribir el código, así que lo anoto aquí para cuando me vuelva a pasar, que entonces, seguramente, ya se me habrá olvidado y me tocará echar otro ratito y no me apetece. El problema es sencillo: hay que ordenar una lista de elementos de forma no trivial. En este caso concreto, hay que ordenar por una propiedad de tipo String, cadena de caracteres, que va a contener resoluciones de imagen, esto es, dos valores numéricos separados por una «x»: 640×480, 1024×768 y así. También serviría para cualquier lista de pares de valores y se podría extender a situaciones más complejas, como coordenadas espaciales y cosas así.

Lo primero ha sido elegir el algoritmo de ordenación. Como van a ser pocos elementos, me he tirado a los sencillitos y, de estos, al de inserción, que es el único que soy capaz de desarrollar sin mirar la chuleta (el de la burbuja lo tengo atravesado). El proceso es muy simple: vamos ordenando por el primer valor. Si este es igual, pasamos a ordenar por el segundo valor. En este caso concreto, ordenamos por largo (primer valor) y si son iguales, por ancho. Para ello, lo primero que he hecho ha sido crearme dos funciones que me devuelvan el largo o el ancho a partir de la cadena:

Private Function ValorNumL(ByVal Resolucion As String) As Integer
    Dim pos As Integer
    pos = Resolucion.ToLower.IndexOf("x"c)
    If pos = -1 Then
        ValorNumL = 0
    Else
        Try
            ValorNumL = CInt(Strings.Left(Resolucion, pos))
        Catch ex As Exception
            ValorNumL = 0
        End Try
    End If
    Return ValorNumL
End Function
Private Function ValorNumA(ByVal Resolucion As String) As Integer
    Dim pos As Integer
    pos = Resolucion.ToLower.IndexOf("x"c)
    If pos = -1 Then
        ValorNumA = 0
    Else
        Try
            ValorNumA = CInt(Strings.Right(Resolucion, _
                            Resolucion.Length - (pos + 1)))
        Catch ex As Exception
            ValorNumA = 0
        End Try
    End If
    Return ValorNumA
End Function

Lo siguiente, implementar la búsqueda. Parto de una List(of IdMasDescripcion) de nombre Resoluciones, donde IdMasDescripcion es una clase que tiene una propiedad, Descripcion, de tipo String, que es por la que vamos a ordenar.

Dim i, j, ElementoLargo, ElementoAncho, jLargo, jAncho As Integer
Dim Elemento As IdMasDescripcion
Dim Menor As Boolean = False
For i = 1 To Resoluciones.Count - 1
    Elemento = Resoluciones(i)
    ElementoLargo = ValorNumL(Elemento.Descripcion)
    ElementoAncho = ValorNumA(Elemento.Descripcion)
    j = i - 1
    Do
        '1) Comparamos primero el largo(lado izdo):
        jLargo = ValorNumL(Resoluciones(j).Descripcion)
        If jLargo > ElementoLargo Then
            Resoluciones(j + 1) = Resoluciones(j)
            j = j - 1
            Menor = False
        ElseIf jLargo = ElementoLargo Then
            'Si son iguales, ordenamos por el ancho
            jAncho = ValorNumA(Resoluciones(j).Descripcion)
            If jancho > ElementoAncho Then
                Resoluciones(j + 1) = Resoluciones(j)
                j = j - 1
                Menor = False
            Else
                Menor = True
            End If
        Else
            Menor = True
        End If
    Loop Until j < 0 OrElse Menor
    Resoluciones(j + 1) = Elemento
Next

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.