distinct() benutzen, um doppelte zahlen aus einem Array zu filtern(C#)?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Linq importieren

dann

array = array.Distinct();

Aber so lange Zufallszahlen zu erzeugen, bis keine doppelten mehr dabei sind, tut mir weh. Da nehme ich lieber eine Liste, aus der ich zufällig Werte herausnehme, oder mische eine Liste (z. B. List<Pair<Double, Int>> mit [Zufallszahl, Index] füllen, nach dem ersten Bestandteil sortieren lassen und die Werte ausfiltern. Leider kann ich gerade nicht ausprobieren, ob Folgendes funktioniert:

public IList<Int> RandomSortedList(Int n) {
    SortedDictionary<Double, Int> dict = new SortedDictionary<Double, Int>;
    for (Int i = 0; i < n; ++i) {
        dict.Add(Math.Random(), i);
    }
    return dict.Values;
}
Woher ich das weiß:Berufserfahrung – Software-Entwickler

Kappaquii 
Fragesteller
 30.01.2020, 22:01

danke, kannst du mir aber erklären, wieso du <double,int> schreibst, bzw wieso du diese größer kleiner zeichen benutzt?

Hast mich auch auf eine Idee gebracht, danke!

LG

0
PWolff  30.01.2020, 22:27
@Kappaquii

Die spitzen Klammern (für die man dummerweise die Kleiner-als- und Größer-als-Zeichen verwendet hat) drücken "Generics" aus. Das bedeutet, man programmiert denselben Code ("generisch") für verschiedene Typen.

Das Konzept macht man sich am besten erst mal an dem ältesten Beispiel klar:

Wenn T ein Typ ist, ist T[] ist der Typ eines Arrays von T.

D. h.

T[Int] intArray;

deklariert intArray als ein Array von Ganzzahlwerten.

Man kann sich darauf verlassen, dass intArray[25] ein Int ist (falls intArray != 0 und 25 ein gültiger Index ist, natürlich), und eine Zuweisung wie

intArray[8] = "siebzehn";

wird gar nicht erst kompiliert.

List ist etwas Ähnliches wie Array, hat aber eine Länge, die sich dynamisch mitändert, wenn man Elemente hinzufügt/entfernt. Für

List<Int> intList;

gilt dasselbe wie für intArray oben gesagt.

Ein Dictionary ist eine Art Wörterbuch, die einen Eintrag in einen anderen übersetzt. Natürlich kann man das auch für seine Vokabellernliste verwenden, aber eben nicht nur.

Hier habe ich ein selbstsortierendes Dictionary "missbraucht", um Int-Werte nach Zufallszahlen sortieren lassen zu können, ohne mir selbst viel Mühe zu machen. Und zwar eins, das ein Double in ein Int "übersetzt". Deshalb Dictionary<Double, Int>.

Als "Nachschlagebegriff" ist ein Double natürlich nicht geeignet - dazu gibt es viel zu viele davon. Aber sie lassen sich sortieren, und ein SortedDichtionary weiß, in welcher Reihenfolge seine Schlüssel(begriffe) auftreten, und damit hoffentlich auch, welcher Reihenfolge seiner rechten Seite, den Werten, das entspricht.

1
Kappaquii 
Fragesteller
 30.01.2020, 22:53
@PWolff

danke für diese ausführlichkeit!

0
Kappaquii 
Fragesteller
 02.02.2020, 22:44

Ich hatte jetzt das hier " SortedDictionary<Double, Int> dict = new SortedDictionary<Double, Int>;" kopiert um zu testen, doch er möchte noch entweder ein (),[], oder {} haben, kann ich einfach vor dem ";" ein () setzen und es funktionert normal?

LG

0
PWolff  02.02.2020, 22:52
@Kappaquii

Ja.

Sorry, das ist mir beim Schreiben des Codes durch die Lappen gegangen.

1
PWolff  02.02.2020, 22:53
@PWolff

Wie üblich gehört auch bei diesem new ein rundes Klammerpaar hinter den Klassennamen:

    SortedDictionary<Double, Int> dict = new SortedDictionary<Double, Int>();
1
Kappaquii 
Fragesteller
 03.02.2020, 15:53
@PWolff

Ich habe deinen code in C# mal eingefügt und dann kam auch nochmal das:

------------------------------------------------------------------------------------------------------------------------------

1.

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand

Fehler CS0117 "Math" enthält keine Definition für "Random".

-----------------------------------------------------------------------------------------------------------------------------------

2.

Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand

Fehler CS0029 Der Typ "System.Collections.Generic.SortedDictionary<double, int>.ValueCollection" kann nicht implizit in "System.Collections.Generic.IList<int>" konvertiert werden.

------------------------------------------------------------------------------------------------------------------------------

das random habe ich gelöst,habe einfach eine methode random gemacht und den part durch random.next ersetzt.

doch kannst du mir beim 2. fehler helfen?

1
PWolff  04.02.2020, 20:51
@Kappaquii
return dict.Values.ToList();

müsste funktionieren

1

Mit Distinct bekommst du nur die Elemente, die nicht doppelt sind.

Beispiel:

var numbers = new int[] { 1, 2, 3, 5, 3, 5 };
var numbersWithoutDuplicates = numbers.Distinct();

Um hingegen die Duplikate zu erhalten, verwende GroupBy:

var numbers = new int[] { 1, 2, 3, 5, 3, 5 };
var duplicates = numbers.GroupBy(number => number)
  .Where(group => group.Count() > 1)
  .Select(group => group.Key);

Beachte, dass das Ergebnis stets ein generisches IEnumerable ist. Wenn du wieder ein Array haben möchtest, verwende ToArray.

Beispiel:

var duplicatesAsArray = duplicates.ToArray();

Kappaquii 
Fragesteller
 30.01.2020, 22:03

danke, ich versuche mal mein können!

0