Frage

Ich habe eine grundlegende C # Konsolenanwendung, die eine Textdatei (CSV-Format), Zeile für Zeile liest und legt die Daten in eine HashTable. Das erste Element in der CSV-Linie ist der Schlüssel (ID NUM) und der Rest der Zeile der Wert ist. Ich habe jedoch festgestellt, dass meine Importdatei ein paar doppelten Schlüssel hat, die es nicht haben sollte. Wenn ich versuche, die Datei mit den Anwendungsfehler zu importieren, weil Sie keine doppelten Schlüssel in einer HashTable haben. Ich möchte mein Programm in der Lage sein, obwohl diese Fehler zu behandeln. Wenn ich in einen doppelten Schlüssel laufen würde Ich mag diesen Schlüssel in eine Arraylist setzen und den Rest der Daten in die Hash-Tabelle zu importieren. Wie kann ich dies in C # tun

Hier ist mein Code:


private static Hashtable Importfile (Hashtable myHashtable, String myFileName)         {

        StreamReader sr = new StreamReader(myFileName);
        CSVReader csvReader = new CSVReader();
        ArrayList tempArray = new ArrayList();
        int count = 0;

        while (!sr.EndOfStream)
        {
            String temp = sr.ReadLine();
            if (temp.StartsWith(" "))
            {
                ServMissing.Add(temp);
            }
            else
            {
                tempArray = csvReader.CSVParser(temp);
                Boolean first = true;
                String key = "";
                String value = "";

                foreach (String x in tempArray)
                {
                    if (first)
                    {
                        key = x;
                        first = false;
                    }
                    else
                    {
                        value += x + ",";
                    }
                }
                myHashtable.Add(key, value);
            }
            count++;
        }

        Console.WriteLine("Import Count: " + count);
        return myHashtable;
    }
War es hilfreich?

Lösung

if (myHashtable.ContainsKey(key))
    duplicates.Add(key);
else
    myHashtable.Add(key, value);

Andere Tipps

Eine bessere Lösung ist ContainsKey zu nennen, wenn der Schlüssel vorhanden zu überprüfen, bevor es in der Hash-Tabelle stattdessen hinzufügen. Werfen Ausnahme auf dieser Art von Fehler ist eine Leistung getroffen und verbessert nicht den Programmablauf.

ContainsKey hat eine konstante O (1) Overhead für jedes Element, während eine Ausnahme fängt eine Performance Hit auf verursacht GERADE die doppelten Elemente.

In den meisten Fällen, überprüfe ich den Schlüssel sagen würde, aber in diesem Fall ist es besser, die Ausnahme zu fangen.

Hier ist eine Lösung, die mit einem kleinen Aufwand für alle Einfügungen mehr Treffer in der sekundären Liste vermeidet:

Dictionary<T, List<K>> dict = new Dictionary<T, List<K>>();

//Insert item
if (!dict.ContainsKey(key))
   dict[key] = new List<string>();
dict[key].Add(value);

Sie können das Wörterbuch in einer Art wickeln, die diese versteckt oder in einem Verfahren setzen oder auch Erweiterungsmethode auf Wörterbuch.

Wenn Sie mehr als 4 (zum Beispiel) CSV-Werte haben, kann es sich lohnen, Einstellung der Wert , sondern auch variabel einen String zu verwenden, da die String-Verkettung eine langsame Funktion ist.

Hmm, 1,7 Millionen Zeilen? Ich zögere, das die Last für diese Art anbieten zu können.

Hier ist eine Möglichkeit, diese mit LINQ zu tun.

CSVReader csvReader = new CSVReader();
List<string> source = new List<string>();
using(StreamReader sr = new StreamReader(myFileName))
{
  while (!sr.EndOfStream)
  {
    source.Add(sr.ReadLine());
  }
}
List<string> ServMissing =
  source
  .Where(s => s.StartsWith(" ")
  .ToList();
//--------------------------------------------------
List<IGrouping<string, string>> groupedSource = 
(
  from s in source
  where !s.StartsWith(" ")
  let parsed = csvReader.CSVParser(s)
  where parsed.Any()
  let first = parsed.First()
  let rest = String.Join( "," , parsed.Skip(1).ToArray())
  select new {first, rest}
)
.GroupBy(x => x.first, x => x.rest)   //GroupBy(keySelector, elementSelector)
.ToList()
//--------------------------------------------------
List<string> myExtras = new List<string>();
foreach(IGrouping<string, string> g in groupedSource)
{
  myHashTable.Add(g.Key, g.First());
  if (g.Skip(1).Any())
  {
    myExtras.Add(g.Key);
  } 
}

Vielen Dank. Ich landete die ContainsKey () Methode verwendet. Es dauert vielleicht 30 Sekunden länger, was für meine Zwecke in Ordnung ist. Ich bin Laden etwa 1,7 Millionen Zeilen und das Programm dauert etwa 7 Minuten insgesamt zwei Dateien zu laden, vergleichen sie, und schreiben Sie ein paar Dateien. Es dauert nur etwa 2 Sekunden die Vergleichs- und schreiben Sie die Dateien zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top