Tipp-Upload: VB.NET 0038: Doppelte Einträge entfernen
von Spatzenkanonier
Über den Tipp
Dieser Vorschlag soll VB.NET Tipp 0042 ersetzen.
Dieser Tippvorschlag wird übernommen.
Der Vorschlag ist in den folgenden Kategorien zu finden:
- Algorithmen
- Listensteuerelemente
Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
listbox,bindinglist,databinding
Der Vorschlag wurde erstellt am: 03.09.2007 04:27.
Die letzte Aktualisierung erfolgte am 16.01.2009 17:15.
Beschreibung
Auch beim Entfernen doppelter Einträge aus einer Listbox erweist es sich als vorteilhaft, nicht "am Control" zu programmieren, sondern an den Daten, und diese per Databinding ans Control zu binden.
(Anzumerken noch, daß das hier gelöste Problem gar nicht entstünde, würde man das Hinzufügen doppelter Einträge von vornherein unterbinden.)
Schwierigkeitsgrad |
Verwendete API-Aufrufe: |
Download: |
' Dieser Source stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' ' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird. ' In den Zip-Dateien ist er jedoch zu finden. ' ---------- Anfang Projektgruppe RemoveDoubles.sln ---------- ' --------- Anfang Projektdatei RemoveDoubles.vbproj --------- ' ------------------ Anfang Datei Form1.vb ------------------ Imports System.ComponentModel Public Class Form1 ' dient der Wiederherstellung des Anfangs-Zustandes Private _Template(2000) As Integer ' die zur Anzeige gebrachten Daten Private _UnderlayingData As New List(Of Integer) ' _DataSource wird als Wrapper um _UnderlayingData initialisiert. Die Bindinglist meldet ' direkte Änderungen sofort an die gebundenen Controls. Änderungen an _UnderlayingData ' dagegen werden nicht "bemerkt". Daher ist in _UnderlayingData eine viel schnellere ' Datenverarbeitung möglich, weil nicht bei jeder Veränderung die angebunden Controls ' benachrichtigt werden. Private _DataSource As New BindingList(Of Integer)(_UnderlayingData) Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load Dim rnd As New Random() For i As Integer = 0 To _Template.Length - 1 _Template(i) = rnd.Next(0, 300) Next _UnderlayingData.AddRange(_Template) ListBox1.DataSource = _DataSource End Sub Private Sub Button_Click(ByVal sender As Object, ByVal e As EventArgs) Handles _ btRestoreSource.Click, btRemoveDoubles.Click, btSort.Click Select Case True Case sender Is btRestoreSource _UnderlayingData.Clear() _UnderlayingData.AddRange(_Template) Case sender Is btRemoveDoubles RemoveDoubles(_UnderlayingData) Case sender Is btSort ' Sortieren der Items macht vorhandene Doppelungen sofort sichtbar _UnderlayingData.Sort() End Select _DataSource.ResetBindings() ' angebundene Controls benachrichtigen End Sub Public Sub RemoveDoubles(Of T)(ByVal lst As List(Of T)) ' Der Algorithmus ist eigentlich ganz unnötig auf Geschwindigkeit optimiert: Das ' hierauf folgende Zeichnen der Listbox wird ca. 500 - 1000 fach langsamer sein. ' (In VB2008 bietet übrigens die Extension-Method "Linq.Enumerable.Distinct()" ' vergleichbare Funktionalität.) Dim known As New Dictionary(Of T, Byte) Dim i As Integer = 0 ' erste Doppelung suchen For i = 0 To lst.Count - 1 Dim itm As T = lst(i) If known.ContainsKey(itm) Then Exit For known.Add(itm, 0) Next ' nach der ersten Doppelung wird der vorlaufende Zähler ii eingeführt, und ' unbekannte Items werden an die Position des jetzt nachlaufenden Zählers i kopiert For ii As Integer = i + 1 To lst.Count - 1 Dim itm As T = lst(ii) If Not known.ContainsKey(itm) Then known.Add(itm, 0) lst(i) = itm i += 1 End If Next lst.RemoveRange(i, lst.Count - i) End Sub End Class ' ------------------- Ende Datei Form1.vb ------------------- ' ---------- Ende Projektdatei RemoveDoubles.vbproj ---------- ' ----------- Ende Projektgruppe RemoveDoubles.sln -----------
Diskussion
Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.
Folgende Diskussionen existieren bereits
Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.