Reputation:
(In this windows form application) I'm trying to read data from a file into a hash table and populate text boxes with the data in the hash table but when I run the code I'm always thrown the exception "Item has already been added. Key in dictionary: '' Key being added: '' "
Initial code:
string[] fileLines = File.ReadAllLines(@"C:path/ajand.txt");
foreach (string line in fileLines)
{
// to split the first 9 chars in the string and use them as key values
string[] match = Regex.Split(line, line.Substring(0,9));
hT.Add(match[0], line);
}
so i tried checking for key duplicates with the following code
string[] fileLines = File.ReadAllLines(@"C:path/ajand.txt");
foreach (string line in fileLines)
{
string[] match = Regex.Split(line, line.Substring(0,9));
if(!hT.ContainsKey(match[0])) // to check duplicates
hT.Add(match[0], line);
}
But when I run the program the corresponding text boxes are not populated with the data that "seems" to have been added to the hash table. Please any ideas what the problem is.
Upvotes: 2
Views: 6324
Reputation: 836
public static Hashtable HashtableFromFile(string path)
{
try
{
using (FileStream stream = new FileStream(path, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
return (Hashtable)formatter.Deserialize(stream);
}
}
catch
{
return new Hashtable();
}
}
Upvotes: 1
Reputation: 3985
See if this helps. It assumes that the separator between the date and the rest of the line is a space. It will try to parse the date into a DateTime object and use it as a key. It will use the rest of the line as the value. The fact that the indexer is used to put values into the dictionary eliminates duplicate key problems, but at the same time it will overwrite values if you have entries that have the same date. In this case only the last entry with that date will be saved into the dictionary.
var lines = File.ReadAllLines(@"C:\path\ajand.txt");
foreach (var line in lines) {
var index = line.Trim().IndexOf(" ");
if (index == -1) {
continue;
}
DateTime key;
if (DateTime.TryParseExact(line.Substring(0, index), out key)) {
hT[key] = line.Substring(index);
}
}
Upvotes: 0
Reputation: 3675
If I understand correctly you could use a function like this one:
public static Dictionary<string, string> LoadActivityLookup(string filePath) {
const int KEY_LENGTH = 10;
var newLookup = new Dictionary<string, string>();
foreach (string line in File.ReadAllLines(filePath)) {
if (line.Length < KEY_LENGTH) continue;
string key = line.Substring(0, KEY_LENGTH);
if (!newLookup.ContainsKey(key)) {
string value = line.Substring(KEY_LENGTH);
newLookup.Add(key, value);
}
}
return newLookup;
}
Dictionaries are great for repeatedly looking up keys in a large set of keys. But if you only need to hold a bunch of key/value pairs in a collection so that you can later iterate through them, I would go with a List<> instead.
Here is a version of the above function which uses a StreamReader instead of loading the complete file in a string array.
public static Dictionary<string, string> LoadActivityLookup(string filePath) {
const int KEY_LENGTH = 10;
var newLookup = new Dictionary<string, string>();
using (StreamReader rdr = new StreamReader(filePath)) {
string line = rdr.ReadLine();
while (line != null) {
if (line.Length < KEY_LENGTH) {
line = rdr.ReadLine();
continue;
}
string key = line.Substring(0, KEY_LENGTH);
if (!newLookup.ContainsKey(key)) {
string value = line.Substring(KEY_LENGTH);
newLookup.Add(key, value);
}
line = rdr.ReadLine();
}
}
return newLookup;
}
Upvotes: 1
Reputation: 10515
In order to remove duplicates, you can simply use the index to add/update to the hashtable:
string[] fileLines = File.ReadAllLines(@"C:path/ajand.txt");
foreach (string line in fileLines)
{
// to split the first 10 chars in the string and use them as key values
string key = line.Length > 10 ? line.Substring(0,10) : line;
hT[key] = line;
}
Upvotes: 0