简体   繁体   English

比较列表<KeyValuePair<> &gt; 在 C# 中

[英]Comparing List<KeyValuePair<>> in C#

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.我正在开发一个需要保存分数和字符串列表的程序,我相信List<KeyValuePair<int, List<string>>>将是最好的列表。 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.我不能使用字典,因为键不是唯一的,所以我使用 Insert 和 BinarySearch 来保持列表排序,我不想在每次插入后使用 List.Sort 因为我要添加很多项目。 ‌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. “列表”按分数降序维护,BinarySearch 检查分数和第一个值是否已在列表中或返回其在列表中的位置,但我无法让比较器工作。 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.在这个例子4, Harry, Miami, Red将是无效的,因为4, Harry...已经存在。 Inserting 9, Dallas... would return 3 as the new position.插入9, Dallas...将返回 3 作为新位置。

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.但是我收到错误CS0535 'Comparer' does not implement interface member 'IComparer<KeyValuePair<int, List<string>>>.Compare(KeyValuePair<int, List<string>>, KeyValuePair<int, List<string>>)'在课堂上。 What am I doing wrong and how can I fix it?我做错了什么,我该如何解决?

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 :整数值与第一个元素的组合是唯一的,您可以使用具有组合该整数和列表的第一个元素作为键的元组的Dictionary

Try the below code yourself自己试试下面的代码

// 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

Judging by the error message the new Comparer() in int index = list.BinarySearch(new KeyValuePair<int, List<string>>(score, values), new Comparer());根据错误信息判断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()不初始化你的private class Comparer : IComparer<KeyValuePair<int, List<string>>>System.Collections.Comparer one.You 应该像这样添加命名空间: new YourNamespaceHere.Comparer()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM