Reputation: 53
Can someone advice me how to prevent this error.
Error is here: dict.Add(sourse[i + 1], target[j + 1]);
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
var sourse = File.ReadAllLines("1.txt", Encoding.Default);
var target = File.ReadAllLines("2.txt", Encoding.Default);
var dict = new Dictionary<string, string>();
for (int i = 0; i < sourse.Length; i += 2)
{
for (int j = 0; j < target.Length; j += 2)
{
if (sourse[i] == target[j])
{
dict.Add(sourse[i + 1], target[j + 1]);
break;
}
}
}
var result = File.ReadAllLines("3.txt", Encoding.Default).ToList();
for (int i = result.Count - 1; i >= 0; i--)
{
foreach (var item in dict)
{
if (result[i].EndsWith(item.Key))
{
result.Insert(i - 1, item.Value);
break;
}
}
}
File.WriteAllLines("result.txt", result, Encoding.Default);
}
}
}
I use Windows 7 64 bit. This code used to work fine. Yesterday stopped working.
Upvotes: 2
Views: 16829
Reputation: 25623
The proper fix depends on what you want to do when there is a collision in the dictionary. If the key already appears, is it indicative of an error? If not, do you want to keep the existing value, or replace it with the new value?
If a collision indicates an error, then using Add
is the correct approach, though you may want to catch
the error and report it in a more 'friendly' manner.
If you want to retain the original value, replace the Add
operation with TryAdd
, which will succeed only if the key does not already exist in the dictionary:
dict.TryAdd(sourse[i + 1], target[j + 1]);
NOTE: The TryAdd
method was added in .NET Core 2.0 and is part of .NET Standard 2.1. If it's not available in your framework version, you can replace it with a check like in @tarik-tutuncu's answer
If you want to replace the existing value and add the new one in its place, you can simply use the 'indexer' syntax, which has "add or replace" semantics:
dict[sourse[i + 1]] = target[j + 1];
There is another possibility, which is that you may have a one-to-many relationship between your keys and values. If that is the case, a simple dictionary isn't going to work, because it can only map a key to a single value. A workaround would be to use a Dictionary<string, List<string>>()
:
var dict = new Dictionary<string, List<string>>();
for (int i = 0; i < sourse.Length; i += 2) {
for (int j = 0; j < target.Length; j += 2) {
if (sourse[i] == target[j]) {
Add(dict, sourse[i + 1], target[j + 1]);
break;
}
}
}
...where Add
is defined as:
private static void Add(Dictionary<string, List<string>> d, string key, string value)
{
if (!d.TryGetValue(key, out var list))
d[key] = list = new List<string>();
list.Add(value);
}
Upvotes: 2
Reputation: 5156
Looks like '1.txt' contains some duplicates. If that's perfectly possible then you need to work out what you want to do in this case.
At the very least you probably want to evaluate whether you have duplicates before doing anything else. At the point you read the lines out of '1.txt' and '2.txt' you probably want to check for duplicates. You can do that by creating something like this:
public bool HasDuplicates(string[] myValues)
{
return myValues.GroupBy(x => x).Any(g => g.Count() > 1);
}
At that point if this returns true you need to decide what to do. If neither of them should have duplicates then should you throw an exception?
On the other hand if this is possible do you need to check which ones are duplicated and then remove one of them? If so this question may help: Finding Duplicate String Arrays
Upvotes: 0
Reputation: 818
Change this part of your code:
if (sourse[i] == target[j])
{
dict.Add(sourse[i + 1], target[j + 1]);
break;
}
to this:
if (sourse[i] == target[j])
{
if (!dict.ContainsKey(sourse[i + 1]))
{
dict.Add(sourse[i + 1], target[j + 1]);
}
break;
}
this will prevent adding a dictionary item with the same key
Upvotes: 3