2017-02-09 69 views
0

我有一本字典(使用C#):如何按键排序字典,如果键是列表(在C#中)?

Dictionary<List<string>, string> dictData = new Dictionary<List<string>, string>(); 

在字典中已经有(例如)值:

key: {"3", "1", "45"}, value: "test value 1" 
key: {"1", "2", "45"}, value: "test value 2" 
key: {"11", "1", "45"}, value: "test value 3" 
key: {"1", "1", "45"}, value: "test value 4" 

关键是一个字符串列表,它会始终保持有至少两个元素。我需要做的是按键对字典进行排序,或者更确切地说,按照列表的第一个元素进行排序,并作为按列表的第二个元素排序的第二个标准。字符串实际上是一个数字,所以它们应该按数字排序(“3”应该小于“11”)。再次

key: {"1", "1", "45"}, value: "test value 4" 
key: {"1", "2", "45"}, value: "test value 2" 
key: {"3", "1", "45"}, value: "test value 1" 
key: {"11", "1", "45"}, value: "test value 3" 

:因此,对于上面的例子,我应该得到以下结果我如何可以排序字典的关键,如果该键实际上是一个列表和通过的第一个元素进行排序列表,然后是列表的第二个元素?

+8

我强烈建议不要使用'List'作为字典 – Jonesopolis

+2

一键如果该键是一个数字,需要如此对待,你为什么要使用字符串列表? –

+1

除了不使用列表作为字典键:如果你真的需要你可以使用'SortedDictionary'与自定义比较器? – Brandon

回答

0

如果你真的需要它作为当前的设置,这个工作(测试代码,这将需要进行调整)。它与原始答案类似,只是完整列表(假设最多3个)。经过测试,似乎正在工作。你将需要添加逻辑,如果它不具有所有3等,这仅仅是一个基础的设置让你去:

private void DoIt() 
    { 
     Dictionary<List<string>, string> test = new Dictionary<List<string>, string>(); 
     List<string> workerList = new List<string>() { "3", "1", "45" }; 
     test.Add(workerList, "test value 1"); 
     workerList = new List<string>() { "1", "2", "45" }; 
     test.Add(workerList, "test value 2"); 
     workerList = new List<string>() { "11", "1", "45" }; 
     test.Add(workerList, "test value 3"); 
     workerList = new List<string>() { "1", "1", "45" }; 
     test.Add(workerList, "test value 4"); 


     foreach(KeyValuePair<List<string>,string> kvp in test.OrderBy(x => int.Parse(x.Key[0])).ThenBy(y => int.Parse(y.Key[1])).ThenBy(z => int.Parse(z.Key[2]))) 
     { 
      Console.WriteLine("Key: " + kvp.Key[0].ToString() + "," + kvp.Key[1].ToString() + "," + kvp.Key[2].ToString() + " | " + "Value: " + kvp.Value.ToString()); 
     } 
    } 

输出:

Key: 1,1,45 | Value: test value 4 
Key: 1,2,45 | Value: test value 2 
Key: 3,1,45 | Value: test value 1 
Key: 11,1,45 | Value: test value 3 
4

如果您有两个List<int>包含:1,2,5和1,2,5,那么这两个列表不是相同的列表。它们是单独的列表实例,它们碰巧包含相同顺序的相同值,因为列表(像其他集合类型,包括阵列)是引用类型。您不能将它们用作唯一键,因为字典会将它们视为不同的键。

我建议建立一个struct包含您的三个值,并将它作为重点。原因是因为结构是一个值类型,并且具有相同属性值的两个实例将被视为相等,这是字典密钥所需的。

struct Values 
{ 
    public int First { get; set; } 
    public int Second { get; set; } 
    public int Third { get; set; } 
} 

然后,你可以这样做:

var x = new Dictionary<Values, string>() 
    { 
     {new Values() {First = 1, Second = 1, Third = 45}, "test value 1"}, 
     {new Values() {First = 1, Second = 2, Third = 45}, "test value 2"}, 
     {new Values() {First = 11, Second = 1, Third = 45}, "test value 3"}, 
    }; 

var sorted = x.OrderBy(kvp => kvp.Key.First).Select(kvp => kvp.Value); 
0

要使用列表作为一个辞典的键,你可以做这样的事情

public class DictionaryKeyList { 

    public List<string> Lst { get; set; } 

    public override bool Equals(Object otherObj){ 
     var otherList = otherObj as DictionaryKeyList; 

     return !this.Lst.Zip(otherList, (a,b) => a == b).Any(x => !x); 
    } 

然后使用字典类型

Dictionary<DictionaryKeyList, string> dictData;