我有一个基本的C#控制台应用程序,它逐行读取文本文件(CSV格式)并将数据放入HashTable。该行中的第一个CSV项是键(id num),该行的其余部分是值。但是我发现我的导入文件有一些不应该有的重复键。当我尝试导入文件时,应用程序错误,因为您不能在HashTable中有重复的键。我希望我的程序能够处理此错误。当我遇到一个重复的密钥时,我想将该密钥放入一个arraylist并继续将其余的数据导入到哈希表中。我怎么能用C#
做到这一点这是我的代码:
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;
}
答案 0 :(得分:10)
if (myHashtable.ContainsKey(key))
duplicates.Add(key);
else
myHashtable.Add(key, value);
答案 1 :(得分:3)
更好的解决方案是调用ContainsKey来检查密钥是否存在,然后再将其添加到哈希表中。在这种错误上抛出异常是性能损失,并没有改善程序流程。
答案 2 :(得分:3)
ContainsKey对每个项目都有一个常量的O(1)开销,而捕获一个Exception会导致对重复的项目产生性能损失。
在大多数情况下,我会说检查密钥,但在这种情况下,更好地捕获异常。
答案 3 :(得分:1)
这是一个解决方案,可避免次要列表中的多次点击,并且所有插入的开销都很小:
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);
您可以将字典包装在隐藏此字典的类型中,或者将其放在字典中的方法甚至扩展方法中。
答案 4 :(得分:1)
如果您有超过4个(例如)CSV值,则可能值得设置值变量以使用StringBuilder,因为字符串连接是一个慢速函数。
答案 5 :(得分:1)
这是使用LINQ执行此操作的一种方法。
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);
}
}
答案 6 :(得分:0)
谢谢大家。 我最终使用ContainsKey()方法。它可能需要30秒更长时间,这对我的目的来说很好。我正在加载大约170万行,程序总共需要7分钟来加载两个文件,比较它们,然后写出几个文件。比较并写出文件只需要大约2秒钟。