textbox doppelte Zeilen ersetzen

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    textbox doppelte Zeilen ersetzen

    Hey,
    Ich habe eine Fragen die ich auch nach 10 Stunden googeln mir nicht beantworten konnte und zwar habe ich eine Textbox:

    Bsp.1
    Bsp.a
    Bsp.a
    Bsp.2
    Bsp.b
    Bsp.b
    Bsp.b
    Bsp.3

    Nach eineBsp.1m Button klick sollte es dann so aussehen

    Bsp.1
    Bsp.2
    Bsp.3

    Es gibt keine regelmäßigen Zeilenabstände und der Text ist unterschiedlich, jedoch IMMER doppelt vorhanden! Ich bitte um eine Idee und einen Beispielcode, das würde mir sehr helfen :)
    Wie wäre es hiermit. Du erstellst eine neue Liste. Darein packst du alle Wörter. Außer wenn sie schon in der Liste vorhanden sind. Also doppelt.
    Zum Schluss löschst du das alte aus der TextBox und fügst alles aus der Liste wieder hinzu.
    Für unerfahrende Programmierer ist es so sehr schön.
    Später kannst du mal überlegen wie man das mit LINQ machen könnte.

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. 'Liste der vorkommenden Wörter
    3. Dim results As New List(Of String)
    4. 'Jede Zeile durchgehen
    5. For Each line As String In TextBox1.Lines
    6. 'Steht das Wort schon in der Liste (Ist es doppelt?)
    7. If Not results.Contains(line) Then
    8. results.Add(line)
    9. End If
    10. Next
    11. 'Text in der TextBox löschen
    12. TextBox1.Clear()
    13. 'Hier muss noch was gemacht werden
    14. 'Wieder alles was in Result steht der TextBox anhängen
    15. End Sub
    @LaMiy
    Les dir nochmal durch, was er genau machen will ;). Er will bei mehrfach vorhandenen Einträgen diese nicht auf einen Eintrag reduzieren sondern komplett entfernen.

    //EDIT:
    Wenn es denn das machen soll, was @LaMiy: sein Code macht, geht das auch in einer einzigen Zeile:

    VB.NET-Quellcode

    1. 'Die Distinct-Funktion entfernt alle Duplikate aus der Aufzählung
    2. Dim Output As String = String.Join(Environment.NewLine, Lines.Distinct())
    3. MessageBox.Show(Output)

    Die Ausgabe sieht so aus:

    Quellcode

    1. Bsp.1
    2. Bsp.A
    3. Bsp.2
    4. Bsp.B
    5. Bsp.3


    Die andere Methode könnte man hingegen zum Beispiel so umsetzen:

    VB.NET-Quellcode

    1. 'Hier werden die Zeilen ausgegeben, welche ok sind
    2. Dim OutputLines As List(Of String) = New List(Of String)
    3. 'Der Zwischenspeicher für die letzten Zeilen
    4. Dim Buffer As List(Of String) = New List(Of String)
    5. 'Alle Zeilen durchgehen
    6. For Each Line As String In Lines.Concat({String.Empty}) 'Dem Lines-Array wird am Ende noch ein Element hinzugefügt, damit die Methode funktioniert
    7. 'Prüfen, ob Zeilen im Zwischenspeicher vorhanden sind und sich die letzte hinzugefügte Zeile von der aktuellen unterscheidet
    8. If Buffer.Count > 0 AndAlso Buffer(0) <> Line Then
    9. 'Prüfen, ob mehrere Zeilen im Zwischenspeicher vorhanden waren und wenn nicht, die Zeile im Zwischenspeicher ausgeben
    10. If Not Buffer.Count > 1 Then OutputLines.Add(Buffer(0))
    11. 'Den Zwischenspeicher leeren
    12. Buffer.Clear()
    13. End If
    14. 'Dem Zwischenspeicher die aktuelle Zeile hinzufügen
    15. Buffer.Add(Line)
    16. Next
    17. 'Den String wieder zusammensetzen und ausgeben
    18. Dim Output As String = String.Join(Environment.NewLine, OutputLines)
    19. MessageBox.Show(Output)

    Hier wäre der Output dann:

    Quellcode

    1. Bsp.1
    2. Bsp.2
    3. Bsp.3

    Hoffe, dass dir das weiterhilft :).

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nafets3646“ ()

    kloputzer95 schrieb:

    Ich bitte um eine Idee und einen Beispielcode, das würde mir sehr helfen
    Ist das nicht ein wenig viel für den Anfang?
    Hier eine Idee ohne Code:
    Pack die Daten in eine List(Of String).
    Sortiere diese Liste.
    Gehe dann die Liste durch und immer, wenn 2 oder mehr gleiche aufeinander folgen, entfernst Du sie aus der Liste.
    Feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    nafets3646 schrieb:

    @LaMiy
    Les dir nochmal durch, was er genau machen will ;). Er will bei mehrfach vorhandenen Einträgen diese nicht auf einen Eintrag reduzieren sondern komplett entfernen.

    //EDIT:
    Wenn es denn das machen soll, was @LaMiy: sein Code macht, geht das auch in einer einzigen Zeile:

    VB.NET-Quellcode

    1. 'Die Distinct-Funktion entfernt alle Duplikate aus der Aufzählung
    2. Dim Output As String = String.Join(Environment.NewLine, Lines.Distinct())
    3. MessageBox.Show(Output)

    Die Ausgabe sieht so aus:

    Quellcode

    1. Bsp.1
    2. Bsp.A
    3. Bsp.2
    4. Bsp.B
    5. Bsp.3


    Die andere Methode könnte man hingegen zum Beispiel so umsetzen:

    VB.NET-Quellcode

    1. 'Hier werden die Zeilen ausgegeben, welche ok sind
    2. Dim OutputLines As List(Of String) = New List(Of String)
    3. 'Der Zwischenspeicher für die letzten Zeilen
    4. Dim Buffer As List(Of String) = New List(Of String)
    5. 'Alle Zeilen durchgehen
    6. For Each Line As String In Lines.Concat({String.Empty}) 'Dem Lines-Array wird am Ende noch ein Element hinzugefügt, damit die Methode funktioniert
    7. 'Prüfen, ob Zeilen im Zwischenspeicher vorhanden sind und sich die letzte hinzugefügte Zeile von der aktuellen unterscheidet
    8. If Buffer.Count > 0 AndAlso Buffer(0) <> Line Then
    9. 'Prüfen, ob mehrere Zeilen im Zwischenspeicher vorhanden waren und wenn nicht, die Zeile im Zwischenspeicher ausgeben
    10. If Not Buffer.Count > 1 Then OutputLines.Add(Buffer(0))
    11. 'Den Zwischenspeicher leeren
    12. Buffer.Clear()
    13. End If
    14. 'Dem Zwischenspeicher die aktuelle Zeile hinzufügen
    15. Buffer.Add(Line)
    16. Next
    17. 'Den String wieder zusammensetzen und ausgeben
    18. Dim Output As String = String.Join(Environment.NewLine, OutputLines)
    19. MessageBox.Show(Output)

    Hier wäre der Output dann:

    Quellcode

    1. Bsp.1
    2. Bsp.2
    3. Bsp.3

    Hoffe, dass dir das weiterhilft :).

    nafets3646 schrieb:

    @nafets3646 Hey danke für deine Antwort, jedoch habe ich zwei Fragen, wo stell ich den die Verbindung zu meiner Textbox also dem Text eigentlich in deinem Quellcode her? Und zweitens, Ist bei mir Lines nicht definiert, wie kann ich das ändern bzw. Als was muss es definiert werden?

    nafets3646 schrieb:


    Lines muss ein IEnumerable(Of String) sein, also z.B. ein String() oder eine List(Of String). Lines kriegst du z.B. durch die Lines-Property in der TextBox so wie es in LaMiy seinem Beispiel gemacht wird.
    @kloputzer95:: Würdest Du bitte die ellenlangen Zitate unterlassen?
    Über welche Vorkenntnisse verfügst Du?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @kloputzer95:
    mit LINQ (ist auch eine schöne Möglichkeit) würde es so gehen...
    In Zeile #2 wird die Liste mit den Einträgen der Textbox1 gefüllt.
    In Zeile #3 wird zuerst die Liste nach Vorkommen der einzelnen Einträge gruppiert und dann wird nur jenes Element mit Vorkommen=1 in die neue Liste Result aufgenommen.

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    2. Dim liste = TextBox1.Text.Split(CChar(Environment.NewLine))
    3. Dim result = ((From txt In liste Group By txt Into cnt = Count()).Where(Function(i) i.cnt = 1))
    4. 'Ausgabe wieder in die Textbox1
    5. TextBox1.Clear()
    6. For Each x In result
    7. TextBox1.Text = TextBox1.Text & x.txt & Environment.NewLine
    8. Next
    9. End Sub

    Ich hoffe - du verstehst den Code?

    VB.NET-Quellcode

    1. Dim Input As List(Of String) = TextBox1.Lines.ToList
    2. TextBox1.Lines = Input.Where(Function(item) Input.IndexOf(item) = Input.LastIndexOf(item)).ToArray


    oder in einem Einzeiler

    VB.NET-Quellcode

    1. TextBox1.Lines = TextBox1.Lines.Where(Function(item) TextBox1.Lines.ToList.IndexOf(item) = TextBox1.Lines.ToList.LastIndexOf(item)).ToArray


    Input:

    Bsp.1
    Bsp.a
    Bsp.a
    Bsp.2
    Bsp.b
    Bsp.b
    Bsp.b
    Bsp.3

    Ausgabe:

    Bsp.1
    Bsp.2
    Bsp.3
    @RushDen
    Coole Idee, was mich jedoch stört ist, dass du global auf Duplikate prüfst (@kloputzer95: Oder soll es das?).
    Trotztem hatte ich noch ne Idee mit der Where-Funktion, welche nur Gruppen von gleichen Elementen entfernt:

    VB.NET-Quellcode

    1. Dim OutputLines = Lines.Where(Function(s, i) Lines.ElementAtOrDefault(i - 1) <> s AndAlso Lines.ElementAtOrDefault(i + 1) <> s)

    Als Code in Verbindung mit TextBoxen könnte das dann so aussehen:

    VB.NET-Quellcode

    1. Dim Lines = TextBox1.Lines
    2. TextBox2.Lines = Lines.Where(Function(s, i) Lines.ElementAtOrDefault(i - 1) <> s AndAlso Lines.ElementAtOrDefault(i + 1) <> s).ToArray()

    Hier noch ein Screenshot um das etwas genauer zu verdeutlichen, was ich meine:

    Der Output bei deinem Beispiel ist allerdings exakt gleich, du musst sagen, was dir passt (@TE).
    MfG Stefan
    @nafets3646
    Dein Code prüft ja nur die Elemente eins unter und drüber vom aktuellen Element, deswegen würde das hier:

    abc
    abc
    abc
    ccc
    abc
    ccc

    was anderes rausgeben als:

    abc
    abc
    abc
    abc
    ccc
    ccc


    obwohl das der gleiche Inhalt ist, nur mit vertauschten Zeilen.
    Der TE meint ja aber es gibt keine regelmäßigen Zeilenabstände, deswegen müsstest du global prüfen.