Distinct-Werte im Array

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Distinct-Werte im Array

    Hallo zusammen,

    ich habe folgende Fragestellung:
    ich habe ein Array mit Strings, von denen einige doppelt vorhanden sind. Nun gibt es die Funktion, die doppelten Werte mit Distinct sozusagen zu vereinfachen.
    Meine Frage ist allerdings diese: Wie kann man nur die einfach vorhandenen Werte herausfiltern, damit alle doppelten gewissermaßen im Array übrig bleiben.
    Bis jetzt habe ich dazu keine Idee...

    Grüße - Dietrich
    Danke für deinen Tipp, Zappler ;) :) !! Sehr gut.

    Allerdings werden "nur" die Elemente gezeigt, die als erste im Array auftreten.
    Ich brauche aber die Information, wenn ein Element mehrfach(2x, 3x...) vorhanden ist, welche weiteren Elemente das sind.
    Vielleicht gibt es dafür auch eine Lösung??

    Grüße - Dietrich
    Dann mach doch mal ein Beispiel...

    Inputarray: {"ab","ab","ac","ac","bc","cb"}

    Mein Resultat: {"ab","ac"}
    Wie stellst du dir dein Resultat vor?
    Deine Beschreibung ergibt für mich keinen Sinn die weiteren Elemente sind = einem vorangegangenem Element, sonst wären sie ja Distinct gewesen und rausgefallen.
    Wenn du die Info brauchst, wie oft ein Element vorkommt, dann lässt du einfach den Select() Teil raus. Dann kriegst du die vollständigen Gruppen als Array, bei denen man entsprechend den Count abfragen kann.

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

    Ja genau wie dein Beispiel ist auch mein Array aufgebaut.
    Mein Resultat sollte sein: ab,ab, ac, ac
    (Background: Ich habe in Array von Filenamen aus verschiedenen Foldern ermittelt, Folder und Subfolder. Das Ergebnis ist ein Array, das alle Filenamen enthält, und da sind eben einige gleich mehrfach dabei. Genau diese Liste von Filenamen, die mehrfach auftauchen, benötige ich, um eventuell dann einige Files zu löschen.)
    Und was bringt Dir dann folgendes, zu erwartendes Ergebnis? Denn sowas wirst Du bekommen.
    TestFile1.txt, TestFile1.txt, TestFile1.txt, TestFile1.txt, AnotherFile.dat, AnotherFile.dat, AnotherFile.dat
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Zed: Ich habe da noch die Zuordnung der Filenamen zu den entsprechenden Foldern, kann also sehen, in welchen unterschiedlichen Foldern dasselbe File gespeichert ist. Dann kann ich die "überflüssigen" Files löschen...

    @Zappel:
    Ich habe mal deinen Vorschlag probiert:
    'Dim result() As String = allFiles.GroupBy(Function(x) x).Where(Function(x) x.Count > 1).Select(Function(x) x.Key).ToArray
    Dim result() As String = allFiles.GroupBy(Function(x) x).Where(Function(x) x.Count > 1).ToArray
    Erste Zeile ist dein ursprünglicher Tipp, zweite Zeile weggelassenes Select -das bringt allerdings einen Fehler...
    "Das Objekt des Typs "System.Linq.IGrouping`2[System.String,System.String][]" kann nicht in Typ "System.String[]" umgewandelt werden."
    Halte ich auch für redundant, dass so wieder auszugeben.
    Guck dir mal

    VB.NET-Quellcode

    1. Dim lookilooki = input.GroupBy(Function(x) x).ToArray
    an
    Jedes darin enthaltene Element hat die Property Key (dein Eintrag) und Count (wie oft dieser vorkommt). Also "ab" mit 2 und "ac" mit 2 im Beispiel.
    Damit muss bereits alles machbar sein, was du mit einem solchen handgeknüpften Array machen könntest, denn beide Ergebnisse sind isomorph

    Da kommt halt kein Stringarray mehr raus, deswegen die Fehlermeldung, sondern ein Array von IGrouping. Du gehst in etwa so damit um

    VB.NET-Quellcode

    1. For each g in lookilooki
    2. Dim eintrag = g.Key
    3. Dim vorkommen = g.Count
    4. Next

    Was willst du anschließend mit result bewerkstelligen?

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

    dherr schrieb:

    Ich habe da noch die Zuordnung der Filenamen zu den entsprechenden Foldern
    Wie willst Du bei dem Ergebnis TestFile1.txt, TestFile1.txt, TestFile1.txt, TestFile1.txt feststellen, welche Datei davon in welchem Verzeichnis ist? Du bekommst da Strings raus. Pure Texte ohne weitere Zusatzinfos. Das heißt, der Code beseitigt Infos, die Du brauchst. Der vermeintliche Wunschcode führt Dich weit weg vom Ziel. Wie im Vorpost steht: GroupBy reicht. Da sind noch alle Infos enthalten. Ab einem nachfolgenden Select gehen Infos verloren.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Zed: Die Zuordnung der Files zu den Foldern habe ich im Vorfeld schon gemacht, sie stehen in der gleichen Reihenfolge in einem Array wie die Filenamen in allFiles. Also Filename und Foldername haben denselben Index in ihren entsprechenden Arrays.
    Mach, wie Du es für richtig hältst. Auf Übereinstimmung von Arrayindices dauerhaft zu hoffen, wäre mir zu heikel. Das GroupBy führt bei korrekter Anwendung zu genau den Ergebnissen, die hier anscheinend gebraucht werden und man hat alle Infos so beieinander wie benötigt. Zumindest habe ich das bei mir immer und immer wieder festgestellt. Aber es ist Dein Programm und Deine Erfahrung.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

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

    Zum ersten Teil, kann das so gelöst werden.

    C#-Quellcode

    1. var str = new string[] { "", "ma", "me", "mi", "mo", "mu", "", "mi" };
    2. var k = str.GroupBy(x => x).Where(y => y.Count() == 1).Select(z => z.Key);
    3. var r = str.Where(x => !k.Contains(x))/*.OrderBy(y=>y)*/.ToArray();
    4. var rr = str.GroupBy(x => x).Where(y => y.Count() > 1).SelectMany(xx => xx);

    VB.NET-Quellcode

    1. Dim str = New String() { "", "ma", "me", "mi", "mo", "mu", "", "mi"}
    2. Dim k = str.GroupBy(Function(x) x).Where(Function(y) y.Count() = 1).[Select](Function(z) z.Key)
    3. Dim r = str.Where(Function(x) Not k.Contains(x)).ToArray()
    4. Dim rr = str.GroupBy(Function(x) x).Where(Function(y) y.Count() > 1).SelectMany(Function(xx) xx)


    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „exc-jdbi“ ()

    Neu

    Hi, ich mache es jetzt folgendermaßen:
    Ausgangspunkt ist eine Datentabelle mit den Spalten Folder, File, Index
    Dann

    Visual Basic-Quellcode

    1. Dim dupfi = From row In Data.AsEnumerable()
    2. Let file = row.Field(Of String)("File")
    3. Group row By file Into DupFiles = Group
    4. Where DupFiles.Count() > 1
    5. Select DupFiles

    Aus dupfi hole ich zwei Stringfelder raus. Eines enthält die Foldernamen, das andere die Filenamen.
    Ich trenne das, weil ich in einer Listbox nur die Feilenamen anzeigen will. Die Zuordnung des Folders erfolgt dann mittels Tooltip, sodass der Nutzer erkennen kann, welches File er dann beim eventuellen anklicken selektiert. Diese kann dan gelöscht werden oder nicht.
    Danke für alle die Tipps von euch!!!

    Grüße - Dietrich

    Neu

    Guck dir mal die Klasse FileInfo an. Die hat die Property Name und FullName. Das eine ist der DisplayMember deiner ListBox, das andere kannst du im Tooltip anzeigen.
    Eine List(Of FileInfo) wäre sicherlich deutlich einfacher handzuhaben als so eine komische Tabelle
    Außerdem guck ma hier: Keine Strings in File-ListBox