Doppelt vorkommende Instanzen in einer LIst of herausarbeiten.

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    Doppelt vorkommende Instanzen in einer LIst of herausarbeiten.

    moin,

    ich habe eine funktion vorliegen, mit der konnte ich
    doppelt vorkommende Zahlen in einer LIst (of INteger) herausarbeiten.
    Sie lautet:

    VB.NET-Quellcode

    1. Dim OrderedList = lukas.Fehlendekarten.OrderBy(Function(x) x)
    2. Dim NumbersWhichEncouterMoreThanOneTime =
    3. lukas.Fehlendekarten.Where(Function(x) OrderedList.Count(Function(y) x =
    4. y) > 1).Distinct
    5. Dim TheOthers = lukas.Fehlendekarten.Except(NumbersWhichEncouterMoreThanOneTime)


    Nun habe ich das Problem, dass es sich jetzt um LIst of Karten handelt und das ganze funktioniert nicht mehr.
    Kann man das dennoch irgendwie umsetzen?

    Der Fehler ist in Zeile 4 und lautet : (unterstichen wird "x = y")
    Fehler
    1 Der =-Operator ist für die Typen
    "Uebungen015_Kartenbörse.Karte" und "Uebungen015_Kartenbörse.Karte"
    nicht definiert.

    In Zeile 6 kommt der Fehler: Fehler 2
    "Option Strict On" lässt keine impliziten Konvertierungen von Object in
    System.Collections.Generic.IEnumerable(Of Uebungen015_Kartenbörse.Karte)
    zu.

    danke
    Zwei Instanzen auf die selbe Identität zu prüfen, geht nicht mit = sondern Is
    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.
    Wattis dattn?

    VB.NET-Quellcode

    1. Dim NumbersWhichEncouterMoreThanOneTime = lukas.Fehlendekarten.Where(Function(x) OrderedList.Count(Function(y) x = y) > 1).Distinct
    Insbesondere was ist y?



    Deine Frage formuliere ich mal um:
    ich möchte doppelt vorkommende Instanzen in einer LIst(of Karte) herausarbeiten.

    Prinzipiell geht das mit .GroupBy() - da erhält man ja Gruppen.
    Und diejenigen Gruppen, die mehr als ein Mitglied haben enthalten offsichtlich Dubletten.
    Nun heisst Groupby GroupBy, und dieses By stellt quasi die Frage, nach welcher eigenschaft die elemente denn gruppiert werden sollen.
    Dazu müsste man die Klasse Karte kennen, ob es da eine Eigenschaft gibt, nach der zu gruppieren sinnvoll wäre.
    Hier mal C#-Linq-basierend:

    C#-Quellcode

    1. .Where(p => l.GroupBy(a => a).Where(b => b.Count() != 2 && b.Key == p).Count() != 0).ToList();


    Der Code kann wahrscheinlich optimiert werden - was es macht: Ich selektiere alle diejenigen Elemente die folgende Bedingung erfüllen:
    Ich gruppiere zuerst anhand des Elements (selbe Elemente werden zur selben Gruppe zusammengefasst, siehe @ErfinderDesRades ' Antwort), dann wende ich
    auf das Ergebnis die .Count() - Funktion an, dieser zählt mir die Anzahl der Elemente pro Gruppe, sodann prüfe ich welche Elemente nicht doppelt vorkommen und ermittle zudem ob die Elementgruppe mit dem momentan zu untersuchende Element übereinstimmt - falls diese Bedingungen erfüllt sind, ist die Anzahl der Elemente in der Gruppe nicht 0 und werden damit selektiert.
    _
    Und Gott alleine weiß alles am allerbesten und besser.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „φConst“ ()

    so also mich würde mal interessieren wie man lernt solche funktionen zu erstellen, weil das sind ja doch einige komponenten die man berücksichtigen muss und kann mir vorstellen dass man da erst mit einfacheren funktionen arbeiten lernt und sich dann steigert? oder wie war das bei euch?

    ich habe das jetzt mal umgesetzt indem ich "=" durch "is" ersetzt habe. das sieht jetzt so aus:

    VB.NET-Quellcode

    1. Dim NumbersWhichEncouterMoreThanOneTime = lukas.Fehlendekarten.Where(Function(x) OrderedList.Count(Function(y) x Is y) > 1).Distinct


    kann das allerdings weder ins listbox anzeigen lassen noch in messagebox, es erscheint die meldung:

    Zusätzliche Informationen: Mindestens ein Objekt muss IComparable implementieren.

    Visual_Prog schrieb:

    so also mich würde mal interessieren wie man lernt solche funktionen zu erstellen, weil das sind ja doch einige komponenten die man berücksichtigen muss und kann mir vorstellen dass man da erst mit einfacheren funktionen arbeiten lernt und sich dann steigert? oder wie war das bei euch?
    Naja, man muss halt die Programmiersprache lernen, zb was ist ein Interface und was bedeutet implementieren.
    Dann versteht man auch solche Fehlermeldungen.
    Man muss halt immer wissen was man tut.
    Das verbietet nicht, Code aussm Internet einzupasten. Aber wenns funktioniert, muss man herausbekommen, warum.
    Wie gesagt: Wissen was man tut.
    ZB das hier:

    Visual_Prog schrieb:

    ich habe das jetzt mal umgesetzt indem ich "=" durch "is" ersetzt habe.
    Warum hast du das gemacht?

    (Manchmal bringt es auch einen Thread voran, wenn man auf Fragen antwortet. Etwa in post#3 habich auch was gefragt.)

    Visual_Prog schrieb:

    so also mich würde mal interessieren wie man lernt solche funktionen zu erstellen

    Naja, erstmal: Ich habe keine Funktion geschrieben, sondern einen Funktionsaufruf formuliert - wie diese Formulierung zustande kommt? SQL... lern SQL-Abfragen, dann kannst du auch Linq.
    Macht irgendwann viel Spaß.

    Wieso verwendest du nicht einfach den Ansatz den ich dir geliefert habe?
    VB-Äquivalent sähe so aus:

    VB.NET-Quellcode

    1. .Where(Function(p) l.GroupBy(Function(a) a).Where(Function(b) b.Count() <> 2 AndAlso b.Key = p).Count() <> 0).ToList()


    Der =-Operator prüft bei Primitiven auf denselben Wert, bei nicht-primitiven Objekten aber auf Instanz - also genau das was du doch haben wolltest?
    _
    Und Gott alleine weiß alles am allerbesten und besser.
    ok danke für das Feedback.

    @ErfinderDesRades ok in diesem fall musste ich das einpasten, weil es mich im projekt ordentlich voranbrint , auch wenn es mir selber noch nicht 100% einleuchtet. Warum da ein y kommt, weiß vielliecht @VaporiZed, der hat das glaube ich ursprünglich erstellt.

    @φConst ja das klingt ja alles spannend, lohnt sich sicher sich damit auseinander zu setzen.
    ich hatte schon deinen Ansatz im Übersetzer eingegeben, jedoch spuckte der nichts raus, insofern danke fürs übersetzen^^

    insofern passiert jetzt folgendes:
    lukas.fehlendekarten besitzt seine fehlende Karten
    nun fügt man dieser list of karten die karten von miriam zu. hier mit spielerliste(1) bezeichnet.

    VB.NET-Quellcode

    1. lukas.Fehlendekarten.AddRange(spielerliste(1).Doppeltekarten)


    es wird eine neue liste deklariert, wo in der nun gemeinsamen liste (fehlendekarten von lukas und doppelte karten von miriam), die karten, die 2 mal vorkommen, entfernt werden. Es bleiben die Karten über, die ihn fehlen und die sie über hat, aber NICHT gemeinsam sind.

    VB.NET-Quellcode

    1. Dim lukasordered = lukas.Fehlendekarten.Where(Function(p) lukas.Fehlendekarten.GroupBy(Function(a) a).Where(Function(b) b.Count() <> 2 AndAlso b.Key Is p).Count() <> 0).ToList()


    in eine dritte liste kommen nun die karten, die doppelt vorkommen und somit zwischen lukas und miriam tauschbar sind.

    VB.NET-Quellcode

    1. Dim lukasmatches = lukas.Fehlendekarten.Except(lukasordered)


    als nächstes werde ich dieses vorgehen zwischen lukas und allen weiteren 6 spielern durchlaufen lassen und diese endliste lukasmatches zählen, um sozusagen das effektivste match zu finden, bei dem lukas möglichst viele fehlende karten durch möglichst viele doppelte karten eines anderes abgedeckt werden. Muss mal schauen ob sich dann dazu weitere Fragen ergeben.
    Ja, hatte ich, aber nur als Anmerkung, warum x = y nicht klappt. Das Problem da lag an anderer Stelle: Dim OrderedList = lukas.Fehlendekarten.OrderBy(Function(x) x) Woher soll der Compiler wissen, wie er sortieren soll?
    Wenn es 3 Karten gibt:
    ID
    Name
    Farbe
    1
    König
    Karo
    2
    Dame
    Herz
    3
    Ass
    Kreuz

    Woher soll der Compiler wissen, welches Kriterium für die Sortierung relevant ist? Denn das hattest Du nicht angegeben. Das ginge dann mit z.B.

    VB.NET-Quellcode

    1. Dim OrderedList = lukas.Fehlendekarten.OrderBy(Function(x) x.Name)

    @φConst: (Du bist schwer zu zitieren): Besitzen ist das falsche Wort. Er kennt sie. Denn in Gedanken kann ich mir auch für mich ne Liste von Sammelkarten machen, die mir fehlen.
    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.
    @VaporiZed @φConst ja es ist genau wie Vaporized sagt, er kennt die fehlenden Karten, besitzen war nicht geschickt formuliert.

    kann man lukasordered und lukasmatches auch als array deklarieren?

    so nach dem motto:

    VB.NET-Quellcode

    1. Dim lukasordered() As List(Of Karte)
    2. Dim lukasmatches() As List(Of Karte)
    3. Dim lukasordered(0) = lukas.Fehlendekarten.Where(Function(p) lukas.Fehlendekarten.GroupBy(Function(a) a).Where(Function(b) b.Count() <> 2 AndAlso b.Key Is p).Count() <> 0).ToList()
    4. Dim lukasmatches(0) = lukas.Fehlendekarten.Except(lukasordered)

    es erscheint : Die lokale Variable "lukasordered" bzw "lukasmatches" ist bereits im aktuellen Block deklariert.

    DIe klasse mit den Fehlendenkarten sieht zur unter anderem zur Zeit so aus, muss man dann hier auch die Fehlendekarten in einem Array umwandeln?

    VB.NET-Quellcode

    1. Public Class Spieler
    2. Public _Fehlendekarten As List(Of Karte)
    3. Public Property Fehlendekarten As List(Of Karte)
    4. Get
    5. Return _Fehlendekarten
    6. End Get
    7. Set(value As List(Of Karte))
    8. _Fehlendekarten = value
    9. End Set
    10. End Class

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

    VB.NET-Quellcode

    1. Dim lukasmatches() As List(Of Karte)
    2. Dim lukasordered(0)

    Doppelte Definition …
    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.
    soweit ich gesehen habe ist fileinfo zum manipulieren von dateien, aber ich möchte hier erstmal dabei bleiben, keine dateien zu handhaben, denn ich habe im code schon eine simulation laufen, die meine listboxen befüllt und brauche dann eigentlich keine dateien.

    da ich das nicht als array hinbekommen habe, habe ich jetzt den matching-prozess von lukas mit jedem spieler einzeln deklariert, danach erfolgt dann die zurücksetzung von lukas.fehlendekarten, denn ich brauche die in deren ursprungsform, denn im matching-prozess wird diese liste ja verändert.
    Bin nicht wirklich zu frieden damit, es sei denn, ihr sagt es ist normal, so viele listen auf diese Weise zu deklarieren.

    VB.NET-Quellcode

    1. lukas.Fehlendekarten.AddRange(spielerliste(1).Doppeltekarten)
    2. Dim lukasordered = lukas.Fehlendekarten.Where(Function(p) lukas.Fehlendekarten.GroupBy(Function(a) a).Where(Function(b) b.Count() <> 2 AndAlso b.Key Is p).Count() <> 0).ToList()
    3. Dim lukasmatches = lukas.Fehlendekarten.Except(lukasordered)
    4. For i = 0 To 6
    5. spielerliste(i).Fehlendekarten.Clear()
    6. spielerliste(i).Fehlendekarten.AddRange(_Kartenliste.Except(spielerliste(i).Eigenekarten))
    7. Next
    8. lukas.Fehlendekarten.AddRange(spielerliste(2).Doppeltekarten)
    9. Dim lukasordered02 = lukas.Fehlendekarten.Where(Function(p) lukas.Fehlendekarten.GroupBy(Function(a) a).Where(Function(b) b.Count() <> 2 AndAlso b.Key Is p).Count() <> 0).ToList()
    10. Dim lukasmatches02 = lukas.Fehlendekarten.Except(lukasordered02)
    11. For i = 0 To 6
    12. spielerliste(i).Fehlendekarten.Clear()
    13. spielerliste(i).Fehlendekarten.AddRange(_Kartenliste.Except(spielerliste(i).Eigenekarten))
    14. Next
    15. lukas.Fehlendekarten.AddRange(spielerliste(3).Doppeltekarten)
    16. Dim lukasordered03 = lukas.Fehlendekarten.Where(Function(p) lukas.Fehlendekarten.GroupBy(Function(a) a).Where(Function(b) b.Count() <> 2 AndAlso b.Key Is p).Count() <> 0).ToList()
    17. Dim lukasmatches03 = lukas.Fehlendekarten.Except(lukasordered03)