Laden...

30000 Datensätze aus txt sortieren und zusammenfassen

Erstellt von Mackerlama vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.336 Views
M
Mackerlama Themenstarter:in
118 Beiträge seit 2008
vor 14 Jahren
30000 Datensätze aus txt sortieren und zusammenfassen

Hallo,

tut mir leid für die schwammige Überschrift.

Ich möchte folgendes tun. Eine Textdate einlesen, die 30000 Datensätze enthält. (Zeile gleich Datensatz, Spalten durch Semikolon getrennt). Daten auf ein Tupel aus Nummer und Menge reduzieren und nach Nummer die Mengen addieren (Datei ist nicht sortiert und Nummern kommen mehrfach vor)

Das Einlesen und reduzieren ist kein Problem. Jedoch weiß ich nicht so recht, welche Datenstruktur sich für mein Vorhaben besonders eignet. Bisher versuchte ich Alles mit Arrays vom Typ string zu machen. Zu mindest die Nummer könnte doch gleich als Int gegriffen werden. Bei der Menge ist eine Besonderheit, dass Sie mit Nullen auf 5-stellen aufgefüllt wird in der Textdatei.

B
293 Beiträge seit 2008
vor 14 Jahren

Warum erstellst du dir keinen eigenen Datentyp mit deinem int und string und machst dann eine List<T> von deinem DatenTyp T?

Viele Grüße

Wenn ich nicht hier bin, findest du mich auf code-bude.net.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Realnub,

nach der groben Beschreibung würde ich

Dictionary <int, HashSet <String>>

vorschlagen.

herbivore

M
Mackerlama Themenstarter:in
118 Beiträge seit 2008
vor 14 Jahren

vielech dank für eure antworten.

mit generischen klassen, wie z.b. Dictionary, kenne ich mich quasi noch gar nicht aus. werde mich aber mal einlesen. (den thread ArrayList vs List<T> habe ich schon gelesen und für sinnig befunden 😃 )

3.825 Beiträge seit 2006
vor 14 Jahren

Hallo Realnub,

was willst Du mit den Daten machen ? In einer Datenbank speichern ?

Das Einlesen und reduzieren ist kein Problem. Jedoch weiß ich nicht so recht, welche Datenstruktur sich für mein Vorhaben besonders eignet.

dann würde ich string[] nehmen :


...
string[] txt = File.ReadAllLines("Text.csv", Encoding.GetEncoding(1252));
foreach (string txt2 in txt)
{
    string[] txt3 = txt.Split(';');
    ds.Tables[0].Rows[i]["test"] = txt3[0];
    ...
}
ds.Update(..)

Wozu die Werte umständlich in Zwischen-Variablen speichern, gleich ab damit ins Dataset und am Ende das Dataset speichern.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

J
1.114 Beiträge seit 2007
vor 14 Jahren

Dictionary <int, HashSet <String>>

Wobei vielleicht schon ein
Dictionary<int, int>

ausreichen könnte.

Er will ja nur für jede Nummer die aufsummierten Mengen haben.

M
Mackerlama Themenstarter:in
118 Beiträge seit 2008
vor 14 Jahren

hallo, in eine datenbank soll das ganze nicht kommen

es gibt mir nur darum, zu erkennen wie sich das mengenverhalten gestaltet. ob es diverse ausreiser nach oben bzw. unten gibt oder ob sich alles um einen punkt konzentriert.

es handelt sich auch nicht um eine textdatei mit 30000 datensätzen sondern um tausende solcher dateien (falls nötig).

weil ich immer noch zu c# bzw. .net anfängern gehöre, wollte ich das ganze vernünftig angehen und kein wildes gecode machen, was zwar auch zum ziel führen kann, aber wohl wesentlich problemanfälliger und unperformanter ist. ausserdem kann es sein, dass ich je nach ergebniss erweiterungen machen muss.

p.s. ich frage mich, warum ich nicht gleich von anfang an konkreter meine problemstellung erläutert habe.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Jelly,

Er will ja nur für jede Nummer die aufsummierten Mengen haben.

das kommt darauf an, was man unter "die Mengen addieren" versteht. Ich würde mal auf die Vereinigungsmenge tippen. Aber Realnub kennt ja jetzt beide Vorschläge und kann daher selbst entscheiden, was auf seine Situation passt.

Hallo Realnub,

weil ich immer noch zu c# bzw. .net anfängern gehöre, wollte ich das ganze vernünftig angehen und kein wildes gecode machen

das ist sehr löblich! Nur kannst du wegen [Hinweis] Wie poste ich richtig? Punkt 1.1.1 das Thema auch nicht endlos ausdehnen. Den Umgang mit Collection setzen wir als bekannt voraus. Ich denke, mit den Anhaltspunkten, die du jetzt hast, müsstest du auch alleine klarkommen. Dictionary und Hashset haben den Vorteil, dass sie auch bei großen Datenmengen immer noch performant bleiben. Versuch es mal damit.

herbivore

M
Mackerlama Themenstarter:in
118 Beiträge seit 2008
vor 14 Jahren
Dictionary.Add() + ArgumentException vs. Dictionary.ContainsKey()

[EDIT=herbivore]Threads zusammengefügt[/EDIT]

Hallo,

ursprünglich habe ich diesen Thread (unter anderem Titel) wie folgt begonnen:

ich lese eine Textdatei ein. Räume etwas auf und schiebe einen Teil der gewünschten Daten in ein Dictionary <int, int>.

Unter Anderem nutze ich die ArgumentException der Add()-Methode um den Value für einen Key summieren zu können. (Anmerkung: die Keys kommen in der Textdatei mehrfach vor)

try  
{  
   masterData.Add(articleNumber, orderQuantity);  
}  
catch(ArgumentException)  
{  
   //key existing -> sum up  
   int articleQuantity = masterData[articleNumber];  
   masterData[articleNumber] = articleQuantity + orderQuantity;  
}  

Mir erscheint es aber falsch, eine Exception für das Aufsummieren zu nutzen.

Gibt es einen alternativen Weg?

An dieser Stelle begann ich mit Denken 😃
Schließlich kam ich dann auf eine Lösung.
--> Vor jedem Aufruf von Add() erst prüfen, ob der Key schon existiert

if (masterData.ContainsKey(articleNumber))
{
   //key existing - sum up
   int articleQuantity = masterData[articleNumber];
   masterData[articleNumber] = articleQuantity + orderQuantity;
}
else
{
   //key new
   masterData.Add(articleNumber, orderQuantity);
}

Das Ende vom Lied:über ArgumentException: ca. 75s über ContainsKey(): < 1s**

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo Realnub,

da du den Wert zu dem Key ja auch immer auslesen willst, wenn der Key existiert, solltest du noch besser Dictionary<>.TryGetValue verwenden.

herbivore

M
Mackerlama Themenstarter:in
118 Beiträge seit 2008
vor 14 Jahren

ah ok, danke.

das ist ja sogar noch einen ticken schneller (siehe hier)

int articleQuantity = 0;

if (masterData.TryGetValue(articleNumber, out articleQuantity))
{
    //existing key - sum up
    masterData[articleNumber] = articleQuantity + orderQuantity;
}
else
{
    //new key
    masterData.Add(articleNumber, orderQuantity);
}
3.971 Beiträge seit 2006
vor 14 Jahren

Wenn du weißt, dass es sich ca. um 30.000 Datensätze handelt, kannst du beim Initalisieren von Dictionary<> und List<> direkt die Anfangskapazität mitgeben. Das erspart dir teils lästiges Umkopieren(List) bzw. Reorganisieren(Dictionary) der Daten.

Dictionary-Konstruktor (Int32)

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...