Reputation: 15
I'm developing a program which needs to hold a list of scores and strings and I believe a List<KeyValuePair<int, List<string>>>
would be the best list to use. I can't use a Dictionary as the keys are not unique so I use Insert and BinarySearch to keep the list sorted and I don't want to use List.Sort after each insert as I'm adding many items. In my code I have:
private List<KeyValuePair<int, List<string>>> list;
List<string> values = new List<string>
{
value1,
value2,
value3
};
// Insert values
list.Insert(index, new KeyValuePair<int, List<string>>(score, values));
// Find index of new position
int index = list.BinarySearch(new KeyValuePair<int, List<string>>(score, values), new Comparer());
private class Comparer : IComparer<KeyValuePair<int, List<string>>>
{
public int Compare(
KeyValuePair<int, List<string>> x,
KeyValuePair<int, List<string>> y)
{
if ((x.Key == y.Key) && (x.Value[0] == y.Value[0]))
return 0;
if ((x.Key < y.Key) || ((x.Key == y.Key) && (x.Value[0] != y.Value[0])))
return 1;
return -1;
}
}
'list' is maintained in descending score order and BinarySearch checks that the score and first value isn't already in the list or return its position in the list but I can't get Comparer to work. An example list would be:
23, Harry, Ottawa, Green
17, Amy, Venice, Red
17, Sue, Sydney, Blue
4, Harry, Durban, Blue
In this example 4, Harry, Miami, Red
would be invalid as 4, Harry...
already exists. Inserting 9, Dallas...
would return 3 as the new position.
However I get the error CS0535 'Comparer' does not implement interface member 'IComparer<KeyValuePair<int, List<string>>>.Compare(KeyValuePair<int, List<string>>, KeyValuePair<int, List<string>>)'
on the class. What am I doing wrong and how can I fix it?
Upvotes: 0
Views: 291
Reputation: 15247
This looks like the first element of the values has a special meaning.
The combination of the integer value along with that first element being unique, you can use a Dictionary
having a tuple combining that integer and the first element of the list as key :
// A SortedDictionary is like a Dictionary, but automatically sorted on the key
var dict = new SortedDictionary<(int, string), List<string>>();
var key = (23, "Harry");
// If you are using .NET Core 2.0 or above, you can use
/*
* if (!dict.TryAdd(key, new List<string> { "Ottawa", "Green" }))
* Console.WriteLine($"Can't add {key}");
*/
if (!dict.ContainsKey(key))
dict.Add(key, new List<string> { "Ottawa", "Green" });
else
Console.WriteLine($"Can't add {key}");
key = (4, "Harry");
if (!dict.ContainsKey(key))
dict.Add(key, new List<string> { "Durban", "Blue" });
else
Console.WriteLine($"Can't add {key}");
key = (4, "Harry");
if (!dict.ContainsKey(key))
dict.Add(key, new List<string> { "this is", "duplicate" });
else
Console.WriteLine($"Can't add {key}");
key = (17, "Amy");
if (!dict.ContainsKey(key))
dict.Add(key, new List<string> { "Venice", "Red" });
else
Console.WriteLine($"Can't add {key}");
key = (17, "Sue");
if (!dict.ContainsKey(key))
dict.Add(key, new List<string> { "Sydney", "Blue" });
else
Console.WriteLine($"Can't add {key}");
Console.WriteLine("---------------------------------------");
Console.WriteLine("Notice now how sorted is the dictionary");
Console.WriteLine("---------------------------------------");
foreach (var Key in dict.Keys)
{
Console.WriteLine($"dict[{Key}] Contains : ");
foreach (var val in dict[Key])
{
Console.WriteLine($"\t{val}");
}
}
This outputs :
Can't add (4, Harry)
---------------------------------------
Notice now how sorted is the dictionary
---------------------------------------
dict[(4, Harry)] Contains :
Durban
Blue
dict[(17, Amy)] Contains :
Venice
Red
dict[(17, Sue)] Contains :
Sydney
Blue
dict[(23, Harry)] Contains :
Ottawa
Green
Upvotes: 1
Reputation: 48
Judging by the error message the new Comparer()
in int index = list.BinarySearch(new KeyValuePair<int, List<string>>(score, values), new Comparer());
does not initialize your private class Comparer : IComparer<KeyValuePair<int, List<string>>>
but the System.Collections.Comparer one.You should add the namespace to it like this: new YourNamespaceHere.Comparer()
Upvotes: 0