Eliminar elementos repetidos en un Array

Iniciado por okik, 22 Junio 2015, 18:23 PM

0 Miembros y 1 Visitante están viendo este tema.

okik

buenas..

¿Hay alguna forma de eliminar elementos repetidos en un Array?


Me he hecho una función, que me ha costado, el ingeniarlo quiero decir, que es la siguiente:


Código (vbnet) [Seleccionar]
   Public Function DeleteArrayRepetitions(ByVal strArray1() As String, ByVal Sorted As Boolean) As Array
       Dim strArray2(0) As String
       Dim TempElement As String
       Dim Count1 As Integer
       Dim Count2 As Integer
       For Each TempElement In strArray1
           Count1 += 1
           If Count1 = 1 Then strArray2(0) = TempElement
           If Array.IndexOf(strArray1, TempElement, Count1) = -1 Then
               ReDim Preserve strArray2(Count2)
               strArray2(Count2) = TempElement
               Count2 += 1
           End If
       Next
       If Sorted = True Then Array.Sort(strArray2)
       Return strArray2
   End Function



Lo que hace es comprobar uno por uno los elementos del strArray1 y si no está repetido lo pasa al strArray2, hasta completar una lista sin repeticiones. Una vez el strArray2 está completo lo pasa a la función DeleteArrayRepetitions que también es un Array. Es decir, la función devuelve una lista sin repeticiones.



En un intento de reducirlo más, resulta que obtengo un código más o menos igual solo que esta vez usando Array.LastIndexOf en lugar de Array.IndexOf



Código (vbnet) [Seleccionar]
   Public Function DeleteArrayRepetitions(ByVal strArray1() As String, ByVal Sorted As Boolean) As Array
       Dim strArray2(0) As String
       Dim Count As Integer = 0
       Dim Count2 As Integer = 0
       For Each Element In strArray1
           Dim Last As Integer = Array.LastIndexOf(strArray1, Element)
           If Count = Last Then
               ReDim Preserve strArray2(Count2)
               strArray2(Count2) = Element
               Count2 += 1
           End If
           Count += 1
       Next
       If Sorted = True Then Array.Sort(strArray2)
       Return strArray2
   End Function





Para usarlo se hace los siguiente:

Código (vbnet) [Seleccionar]
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim Numbers() As String = {"1", "5", "5", "5", "4", "1", "12", "4", "55"}

'Quita los elementos repetidos
       Numbers = DeleteArrayRepetitions(Numbers, True)

'Lista los elementos del Array en un ListBox
       For Each Element In Numbers
           ListBox1.Items.Add(Element)
       Next
   End Sub


El ListBox mostrará:

1
12
4
5
55


A pesar que las funciones funcionan bien, debe haber alguna forma más sencilla, alguna función en VBNET que permita hacerlo. He probado con Array y ArrayList, pero no he visto nada.

Sl2

El Benjo

Realmente no hay una funcion en .net que te devuelva un array sin elementos repetidos. Todos en alguna ocasión nos hemos encontrado con este problema y debemos implementar nuestras propias funciones para lidiar con él. De hecho la forma en que lo estás haciendo parece sigue el modelo que se utiliza para ello:

· Primer bucle que recorre el array en su totalidad.
·   Segundo bucle que recorre el array después de la posición del bucle 1.
·     Si el elemento no está repetido:
·       Lo agrego al segundo array.
·     Fin
·   Next
· Next
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

Eleкtro

#2
Citar¿Hay alguna forma de eliminar elementos repetidos en un Array?

Cita de: El Benjo en 22 Junio 2015, 21:55 PMRealmente no hay una funcion en .net que te devuelva un array sin elementos repetidos.

Por supuesto que hay una función en la librería de classes de .Net para eliminar duplicados de un Array / Enumerable, usando LINQ:

IEnumerable.Distinct - MSDN

CitarReturns distinct elements from a sequence by using the default equality comparer to compare values.

Ejemplo:
Código (vbnet) [Seleccionar]
Dim values As Integer() = {1, 5, 5, 5, 4, 1, 12, 4, 55}

values = values.Distinct(EqualityComparer(Of Integer).Default).ToArray

MessageBox.Show(String.Join(", ", values))


El argumento que le asigno al parámetro de la extensión Distinct en este caso es innecesario, puedes dejarlo vacío, pero te he mostrado ese overload para denotar que puedes implementar un comparer personalizado y pasárselo cómo parámetro, aunque esto ya requeriría más trabajo.




Cita de: okik en 22 Junio 2015, 18:23 PMHe probado con Array y ArrayList, pero no he visto nada.

La Class Array y ArrayList debes tratar de ignorarlas y omitir su utilización por completo, hay opciones mejores,
te sugiero utilizar una coleccion genérica de tipo List(Of T), la cual puedes utilizar el método List.Add y List.AddRange para añadir nuevos elementos a la colección y de esta manera incrementar dinamicamente la colección, en lugar de ir redimensionando un objeto de tipo Array de forma primitiva.

Ejemplo:
Código (vbnet) [Seleccionar]
Dim int32List As New List(Of Integer) ' From {1, 5, 5, 5, 4, 1, 12, 4, 55}
int32List.AddRange({1, 5, 5, 5, 4, 1, 12, 4, 55})
int32List = int32List.Distinct.ToList

MessageBox.Show(String.Join(", ", int32List))


Saludos!