Benutzer mit den meisten Antworten
Sortierte Dictionary Values addieren

Frage
-
Hallo Leute,
folgender Code erstellt mir ein sortiertes Dictionary. Meine Intention ist es, all jene Values derjenigen Keys, die doppelt(doppelt bzgl. der Keys, nicht der Values) vorhanden sind, aufzuaddieren und das Ergebnis in einer Variablen, optimal in einem neuen Dictionary zu hinterlegen. Wie stelle ich das am elegantesten an? Anmerkung: Der Key kann mittels ConvertToInt32() in ein integer konvertiert werden. Das wirft niemals eine Exception aus! Edit: Merke gerade, dass der Key eines Dictionarys unique sein muss. Könnte man sich das im Exceptionblock nicht zu nutze machen?
Dictionary<string, double> getData = new Dictionary<string, double>(); Dictionary<string, double> newDataAfterAddition = new Dictionary<string, double>();
double newDataAfterAddition_;
foreach(CalculatedMissionTimeBooking booking in bookings) {
.
.
getData = collectData(getData, booking.mechanicGroupNumber, booking.awIsTime);
var items = from pair in getData
orderby pair.Value ascending
select pair;
foreach(KeyValuePair<string, double> pair in items) {
//wie geht's hier am elegantesten weiter?
}}
private static Dictionary<string,double> collectData(Dictionary<string,double> sendDataBack, string number, double time) {
sendDataBack.Add(number,time);
return sendDataBack;
}
- Bearbeitet tklustig Mittwoch, 30. Januar 2019 13:27
Antworten
-
Hi,
mit "prozedural" meine ich eine Folge von Anweisungen, die nacheinander abgearbeitet werden, ohne dass dabei Kapselungen in Klassen mit Nutzung derer Member für diesen Algorithmus in Anwendung kommen. Ein objektorientierter Ansatz könnte im Gegensatz dazu die Nutzung einer eigenen oder abgeleiteten (geerbten) Klasse sein (z.B. vom Dictionary geerbt) mit eigenen Methoden oder auch Extension für diese Klasse oder für Dictionary sein.--
Viele Grüsse
Peter Fleischer (ehem. MVP für Developer Technologies)
Meine Homepage mit Tipps und Tricks- Als Antwort markiert tklustig Donnerstag, 31. Januar 2019 08:37
Alle Antworten
-
Hi,
prozedural geht das ganz einfach:// dic3 = dic1 + dic2
foreach (var d1 in dic1) if (dic2.ContainsKey(d1.Key)) dic3.Add(d1.Key, d1.Value + dic2[d1.Key]);
else dic3.Add(d1.Key, d1.Value);
// Rest von dic2 zu dic3 hinzufügen
foreach (var d2 in dic2) if (!dic1.ContainsKey(d2.Key)) dic3.Add(d2.Key, d2.Value);
--
Viele Grüsse
Peter Fleischer (ehem. MVP für Developer Technologies)
Meine Homepage mit Tipps und Tricks- Bearbeitet Peter Fleischer Mittwoch, 30. Januar 2019 13:43
- Als Antwort vorgeschlagen Peter Fleischer Mittwoch, 30. Januar 2019 13:44
-
Merke gerade, dass der Key eines Dictionarys unique sein muss. Könnte man sich das im Exceptionblock nicht zu nutze machen?
Hi, sehe ich auch so. eine Dictionary mit zwei gleichen Keys ist doch gar nicht möglich...
Ich würde beim befüllen des Dictionarys abfragen, ob der Key schon vorhanden ist und dann gleich den den Value addieren. Aber das in der Exeption zu machen, ist schlechter Stil! und nicht gerade sehr performant...
Also, so wie Peter seine Lösung!
Gruß
Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP
- Bearbeitet Stefan Krömer Mittwoch, 30. Januar 2019 13:51
-
Und wie bekomme ich die Werte in mein Dictionary? Sobald der key doppelt auftritt, wird die Exception
Ein Element mit dem gleichen Schlüssel wurde bereits hinzugefüg
ausgelöst. Eventuell ist ein Dictionary das falsche Generikum. Welches sollte ich sonst wählen, um die Kombination Key=>value zu erfassen, ohne besagte Einschränkung? -
Entweder so, wie Peter es beschrieben hast oder du bearbeitest deine Dictionary.
Ich habe mal eine kleine Consolen-Demo erstellt.
Dictionary<string, double> dic = new Dictionary<string, double>(); for (int i = 0; i < 100; i++) { string key = rnd.Next(1, 10).ToString(); double val = rnd.Next(1, 10); if (dic.ContainsKey(key)) { dic[key] += val; } else { dic.Add(key, val); } } foreach (KeyValuePair<string, double> pair in dic) { Console.WriteLine(pair.Key + "....." + pair.Value); } Console.WriteLine("DONE"); Console.ReadLine();
Es wird eine Dictionary erstellt und in einer Schleife werden 101 zufällige Keys (1-10) und Values (1-10) erstellt und entweder wird ein neues KeyValuePair erstellt oder der Wert von Value einem vorhandenen dazu addiert.
Gruß
Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP
- Bearbeitet Stefan Krömer Mittwoch, 30. Januar 2019 14:30
-
Hallo Peter,
Dein Code scheint einen Syntaxfehler zu haben, zumindest in der Form, wie ich ihn aufgebröselt habe:
/*dic1=sendDataBack dic2=getData2, dic3=getData3*/
foreach(var d1 in sendDataBack) { if(getData2.ContainsKey(d1.Key)) { getData2.Add(d1.Key, d1.Value + getData2[sendDataBack.Key]); } else { getData3.Add(d1.Key, d1.Value); } // Rest von dic2 zu dic3 hinzufügen foreach(var d2 in getData2) { if(!sendDataBack.ContainsKey(d2.Key)) getData3.Add(d2.Key, d2.Value); } }
+getData2[sendDastaBack.Key] geht nicht!
Fehler 2 1-Argument: Kann nicht von "System.Collections.Generic.Dictionary<string,double>.KeyCollection" in "string" konvertiert werden. D:\SVN\C#\TimeTrackingApp\TimeTrackingApp\Program.cs 541 65 TimeTrackingApp Fehler 1 Die beste Übereinstimmung für die überladene System.Collections.Generic.Dictionary<string,double>.this[string]-Methode hat einige ungültige Argumente. D:\SVN\C#\TimeTrackingApp\TimeTrackingApp\Program.cs 541 56 TimeTrackingApp
- Bearbeitet tklustig Mittwoch, 30. Januar 2019 15:03
-
Korrekt. Klappt aber trotzdem nicht. der Algorithmus versagt, zumindest in folgender Form. es besteht immer wieder das Problem, das Keys eingefügt werden, die bereits exisitieren:
private static Dictionary<string, double> collectData(Dictionary<string, double> sendDataBack, string number, double time) { string key = String.Empty; ; foreach(KeyValuePair<string, double> kvp in sendDataBack) { key = kvp.Key; } if(!sendDataBack.ContainsKey(key)) { sendDataBack.Add(number, time); } else { // dic3 = dic1 + dic2 foreach(var d1 in sendDataBack) { if(getData2.ContainsKey(d1.Key)) { getData2.Add(d1.Key, d1.Value + getData2[d1.Key]); } else { //hier wird versucht, key mehrfach einzufügen getData3.Add(d1.Key, d1.Value); } // Rest von dic2 zu dic3 hinzufügen foreach(var d2 in getData2) { if(!sendDataBack.ContainsKey(d2.Key)) getData3.Add(d2.Key, d2.Value); } } } return sendDataBack; }
- Bearbeitet tklustig Mittwoch, 30. Januar 2019 15:16
-
Du fragst, ob in "getData2" ein bestimmter Key vorhanden ist und versuchst dann in "getData3" einen Key hinzuzufügen....
Das ist alles, aber bestimmt nicht sicher!
Zumal niemand weiß, was in "getData2" und "getData3" drinsteckt oder woher das kommt.
Für mich persönlich ist das eh ein schlechter Stil, in einer Funktion oder Methode mit Eingagsparametern und einem Rückgabewert private oder öffentliche Eigenschaften/Variablen zu verwenden..
Und was soll das überhaupt sein? Das macht ja gar keinen Sinn:
string key = String.Empty; ; foreach (KeyValuePair<string, double> kvp in sendDataBack) { key = kvp.Key; } if (!sendDataBack.ContainsKey(key))...
So bekommst doch immer nur den letzten Key aus sendDataBack...
Ok, wenn man das zweimal liest, muss man die Hände über den Kopf zusammenschlagen... Nicht böse gemeint ;)
Aber das was du hier postest, kann nur der Entwurf vom Entwurf einer Idee sein... Eigentlich macht da nichts Sinn..
Gruß
Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP
- Bearbeitet Stefan Krömer Mittwoch, 30. Januar 2019 15:32
-
Nun ja, das ist halt die Interpretation von dem, was Peter als "prozeduralen" Lösungsansatz gepostet hatte. Was immer er mit "prozedural" meinte (C# ist doch durch und durch objektorientiert,oder?). Ich werde das Dictionary jetzt verwerfen und anstatt dessen das Generika
List<Tuple<string, int>> liste = new List<Tuple<string, int>>();
liste.Add(new Tuple<int, string>(integer, string));
verwenden. Den Algorithmus, der mir bei Stringleichheit die dazugehörigen Integerwerte aufaddiert muss ich mir dann halt selber schreiben. So long...
- Bearbeitet tklustig Mittwoch, 30. Januar 2019 19:20
-
Hi,
mit "prozedural" meine ich eine Folge von Anweisungen, die nacheinander abgearbeitet werden, ohne dass dabei Kapselungen in Klassen mit Nutzung derer Member für diesen Algorithmus in Anwendung kommen. Ein objektorientierter Ansatz könnte im Gegensatz dazu die Nutzung einer eigenen oder abgeleiteten (geerbten) Klasse sein (z.B. vom Dictionary geerbt) mit eigenen Methoden oder auch Extension für diese Klasse oder für Dictionary sein.--
Viele Grüsse
Peter Fleischer (ehem. MVP für Developer Technologies)
Meine Homepage mit Tipps und Tricks- Als Antwort markiert tklustig Donnerstag, 31. Januar 2019 08:37