Ordenar listbox ??

Iniciado por luis456, 25 Marzo 2016, 15:29 PM

0 Miembros y 2 Visitantes están viendo este tema.

luis456

Tengo un listbox que tiene registros de esta forma

20, 24, 34
20, 24, 44
20, 24, 45
20, 34, 24
20, 34, 44
20, 45 ,24

necesito ordenarlos para saber cuantas lineas son iguales y haci poder eliminar duplicados explico:

si ordenamos los números de arriba estos quedarían así

ordenados vemos que se repiten
20, 24, 34
20, 24, 44
20, 24, 45****
20, 24, 34****
20, 34 ,45
20, 24, 45 ***

tengo este  código pero lo ordena de menor a mayor


Código (vbnet) [Seleccionar]
Private Sub Button12_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button12.Click
       ListBox1.Sorted = True
       ListBox1.Sorted = False
       Dim i As Integer
       Dim count = ListBox1.Items.Count
       For i = ListBox1.Items.Count - 1 To 0 Step -1
           ListBox1.Items.Add(ListBox1.Items(i))
       Next
       For i = 0 To count - 1
           ListBox1.Items.RemoveAt(ListBox1.SelectedItem)
       Next
   End Sub


alguna sugerencia o ejemplos que pueda conseguir

Luis







Que tu sabiduria no sea motivo de Humillacion para los demas

crack81

Hola puedes revisar esta posible solucion

Código (vbnet) [Seleccionar]
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim list As New List(Of String)
        Dim i As Integer

        For i = 0 To ListBox1.Items.Count - 1
            list.Add(ListBox1.Items(i))
        Next i

        ListBox1.Items.Clear()

        For Each s As String In list.Distinct
            ListBox1.Items.Add(s)
        Next

    End Sub
End Class



Si C/C++ es el padre de los lenguajes entonces ASM es dios.

Eleкtro

#2
Lo estás haciendo todo al revés Luis, primero estás obteniendo una coleccion con sub-colecciones por elementos ( IEnumerable(Of IEnumerable(Of Integer)) ), luego, por cada sub-colección, unes todos los sub-elementos en un string con String.Join(), luego, ese string, el cual contiene la representación de cada sub-colección con saltos de linea, lo partes por un salto de linea ( colección.Split({Environment.NewLine}) ) para obtener de nuevo una colección que insertar en el listbox... y ahora, quieres volver a convertir los elementos del Listbox en un array de enteros para eliminar duplicados.

No se si me he equivocado en algún paso del procedimiento, por que ya solo de pensarlo es un completo lio lo que estás haciendo, tanta conversión de array a string, y viceversa, DEJA DE HACER ESO.

Si quieres eliminar duplicados, entonces hazlo en el momento en el que construyes la colección de combinaciones, NO despues de haberla transformado en no se cuantos tipos de objetos ya :¬¬.

Mi consejo:
Intenta hacer un buen planteamiento de la lógica antes de escribir ningún código, por que luego acabarás con necesidades como esta, me refiero a tener que hacer algo en un paso del proceso en el que ya deberias haberlo hecho... no se si me explico.
Create un Type que herede de una colección genérica, llamemoslo CombinationCollection, y úsalo parra almacenar las combinaciones.
Para representar los valores o combinaciones, en un string, podrías utilizar un proveedor de formato personalizado, es decir, una class que implemente la interface IFormatProvider y ICustomFormatter (el cual usarias como formato personalizado en el método  String.Format()). O simplemente suplantar el método ToString en tu type personalizado.

Es mucho trabajo, como para mostrarte ejemplos de todo, pero en MSDN los puedes encontrar.

Saludos!








luis456

Cita de: crack81 en 25 Marzo 2016, 17:47 PM
Hola puedes revisar esta posible solucion

Código (vbnet) [Seleccionar]
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim list As New List(Of String)
        Dim i As Integer

        For i = 0 To ListBox1.Items.Count - 1
            list.Add(ListBox1.Items(i))
        Next i

        ListBox1.Items.Clear()

        For Each s As String In list.Distinct
            ListBox1.Items.Add(s)
        Next

    End Sub
End Class





Gracias por tu ayuda pero no me elimina ,primero hay que ordenarlos para poder eliminar todas las lineas iguales son muchos registros

saludos
Luis


Que tu sabiduria no sea motivo de Humillacion para los demas

luis456

Cita de: Eleкtro en 25 Marzo 2016, 17:57 PM
Lo estás haciendo todo al revés Luis, primero estás obteniendo una coleccion con sub-colecciones por elementos ( IEnumerable(Of IEnumerable(Of Integer)) ), luego, por cada sub-colección, unes todos los sub-elementos en un string con String.Join(), luego, ese string, el cual contiene la representación de cada sub-colección con saltos de linea, lo partes por un salto de linea ( colección.Split({Environment.NewLine}) ) para obtener de nuevo una colección que insertar en el listbox... y ahora, quieres volver a convertir los elementos del Listbox en un array de enteros para eliminar duplicados.

No se si me he equivocado en algún paso del procedimiento, por que ya solo de pensarlo es un completo lio lo que estás haciendo, tanta conversión de array a string, y viceversa, DEJA DE HACER ESO.

Si quieres eliminar duplicados, entonces hazlo en el momento en el que construyes la colección de combinaciones, NO despues de haberla transformado en no se cuantos tipos de objetos ya :¬¬.

Mi consejo:
Intenta hacer un buen planteamiento de la lógica antes de escribir ningún código, por que luego acabarás con necesidades como esta, me refiero a tener que hacer algo en un paso del proceso en el que ya deberias haberlo hecho... no se si me explico.
Create un Type que herede de una colección genérica, llamemoslo CombinationCollection, y úsalo parra almacenar las combinaciones.
Para representar los valores o combinaciones, en un string, podrías utilizar un proveedor de formato personalizado, es decir, una class que implemente la interface IFormatProvider y ICustomFormatter (el cual usarias como formato personalizado en el método  String.Format()). O simplemente suplantar el método ToString en tu type personalizado.

Es mucho trabajo, como para mostrarte ejemplos de todo, pero en MSDN los puedes encontrar.

Saludos!

Hola bueno Elektro sabes que me baso mucho en tus modelos jejej y por supuestos tus consejos ya que te has pasado con la ayuda que me has dado, pero ciertas cosas son chinas para mi jejje,me acostumbre a trabajar con un tipo de variable y me vuelvo un lio cuando se cambia de modo, por eso es que trato de llevar al terreno que conozco las cosas. lo que pasa es que no quiero tocar tu código, me gustaría resolverlo mas facil y para mi seria poder limpiar el listbox de los resultados duplicados  después que estén hechos, ya sabes que cada quien le tiene una idea especifica a cada cosa  :silbar: y me interesa que tu codigo quede de esa manera.ya que códigos de combinaciones y permutas hay miles jejeje pero no es lo que busco.

saludos
Luis

Que tu sabiduria no sea motivo de Humillacion para los demas

Eleкtro

#5
Bueno Luis... ya que necesitas ayuda con esos códigos que tienes mezclados a tu manera, que le vamos a hacer.

Teniendo un ListBox con los sigueintes items:
Citar1, 2, 3
3, 2, 1
1, 3, 2
2, 1, 3
4, 5, 6
7, 8, 9



El supuesto resultado que creo que esperas obtener es el siguiente:
Citar1, 2, 3
4, 5, 6
7, 8, 9



(Más te vale que sea así, por que no hay quien sea capaz de entender en que sentido son "iguales" :¬¬)

Pues, entonces, una forma sencillita de hacerlo seria implementando tu propio comparer para evaluar duplicados:
Código (vbnet) [Seleccionar]
   Public NotInheritable Class CombinationComparer : Implements IEqualityComparer(Of String)

       Public Shadows Function Equals(ByVal x As String, ByVal y As String) As Boolean _
       Implements IEqualityComparer(Of String).Equals

           ' (temporalmente) Ordeno de forma ascendente los números de una cadena de texto delimitada por comas;
           '
           ' e.g.:
           ' Una cadena de texto como "3, 1, 2" (con, o sin espacios en blanco),
           ' se transformaría en "1,2,3" (sin espacios en blanco).

           x = String.Join(",", From value As String In x.Split({","c, " "c}, StringSplitOptions.RemoveEmptyEntries)
                                Order By value Ascending)

           y = String.Join(",", From value As String In y.Split({","c, " "c}, StringSplitOptions.RemoveEmptyEntries)
                                Order By value Ascending)

           #If DEBUG Then
                       Console.WriteLine(String.Format("x:{0}", x))
                       Console.WriteLine(String.Format("y:{0}", y))
                       Console.WriteLine()
           #End If

           Return (x = y)

       End Function

       Public Shadows Function GetHashCode(ByVal obj As String) As Integer _
       Implements IEqualityComparer(Of String).GetHashCode

           Return MyBase.GetHashCode()

       End Function

   End Class


Y lo emplearías de la siguiente manera:
Código (vbnet) [Seleccionar]
Dim items As String() = Me.ListBox1.Items.Cast(Of String)().ToArray()
items = items.Distinct(New CombinationComparer).ToArray()

With Me.ListBox1
   .SuspendLayout()
   .Items.Clear()
   .Items.AddRange(items)
   .ResumeLayout()
End With

( importante: no olvides de usar la extensión ".ToArray()" como en el ejemplo, para crear una copia de la colección de items del ListBox )

PD:
Si no es ese el resultado que esperas obtener, no te preocupes, te lo he puesto bien facilito al menos el 50% de la tarea, solo tienes que cojer el comparer de ejemplo y realizar las adaptaciones necesarias en la implementación del métobo base IEqualityComparer(Of String).Equals, en la variable "X" e "Y".

Saludos








luis456

Cita de: Eleкtro en 25 Marzo 2016, 21:56 PM
Bueno Luis... ya que necesitas ayuda con esos códigos que tienes mezclados a tu manera, que le vamos a hacer.

Teniendo un ListBox con los sigueintes items:


El supuesto resultado que creo que esperas obtener es el siguiente:


(Más te vale que sea así, por que no hay quien sea capaz de entender en que sentido son "iguales" :¬¬)

Pues, entonces, una forma sencillita de hacerlo seria implementando tu propio comparer para evaluar duplicados:
Código (vbnet) [Seleccionar]
   Public NotInheritable Class CombinationComparer : Implements IEqualityComparer(Of String)

       Public Shadows Function Equals(ByVal x As String, ByVal y As String) As Boolean _
       Implements IEqualityComparer(Of String).Equals

           ' (temporalmente) Ordeno de forma ascendente los números de una cadena de texto delimitada por comas;
           '
           ' e.g.:
           ' Una cadena de texto como "3, 1, 2" (con, o sin espacios en blanco),
           ' se transformaría en "1,2,3" (sin espacios en blanco).

           x = String.Join(",", From value As String In x.Split({","c, " "c}, StringSplitOptions.RemoveEmptyEntries)
                                Order By value Ascending)

           y = String.Join(",", From value As String In y.Split({","c, " "c}, StringSplitOptions.RemoveEmptyEntries)
                                Order By value Ascending)

           #If DEBUG Then
                       Console.WriteLine(String.Format("x:{0}", x))
                       Console.WriteLine(String.Format("y:{0}", y))
                       Console.WriteLine()
           #End If

           Return (x = y)

       End Function

       Public Shadows Function GetHashCode(ByVal obj As String) As Integer _
       Implements IEqualityComparer(Of String).GetHashCode

           Return MyBase.GetHashCode()

       End Function

   End Class


Y lo emplearías de la siguiente manera:
Código (vbnet) [Seleccionar]
Dim items As String() = Me.ListBox1.Items.Cast(Of String)().ToArray()
items = items.Distinct(New CombinationComparer).ToArray()

With Me.ListBox1
   .SuspendLayout()
   .Items.Clear()
   .Items.AddRange(items)
   .ResumeLayout()
End With

( importante: no olvides de usar la extensión ".ToArray()" como en el ejemplo, para crear una copia de la colección de items del ListBox )

PD:
Si no es ese el resultado que esperas obtener, no te preocupes, te lo he puesto bien facilito al menos el 50% de la tarea, solo tienes que cojer el comparer de ejemplo y realizar las adaptaciones necesarias en la implementación del métobo base IEqualityComparer(Of String).Equals, en la variable "X" e "Y".

Saludos

Gracias ya esta solucionado  ;-) ;-) ;-) ;-) ;-) ;-)

saludos
Luis



Que tu sabiduria no sea motivo de Humillacion para los demas