如果key是一个列表(用C#)的话,如何按key对字典排序?

如果key是一个列表(用C#)的话,如何按key对字典排序?,c#,linq,list,sorting,dictionary,C#,Linq,List,Sorting,Dictionary,我有一本字典(用C#): 键是一个字符串列表,它将始终至少包含两个元素。我需要做的是按键对字典进行排序,或者更准确地说,按列表的第一个元素进行排序,并作为第二个标准按列表的第二个元素进行排序。字符串实际上是一个数字,因此它们应该按数字排序(“3”应该小于“11”)。对于上面的例子,我应该得到以下结果: key: {"1", "1", "45"}, value: "test value 4" key: {"1", "2", "45"}, value: "test value 2" key: {"3

我有一本字典(用C#):

键是一个字符串列表,它将始终至少包含两个元素。我需要做的是按键对字典进行排序,或者更准确地说,按列表的第一个元素进行排序,并作为第二个标准按列表的第二个元素进行排序。字符串实际上是一个数字,因此它们应该按数字排序(“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"

再次:如果键实际上是一个列表,并且要由列表的第一个元素执行排序,然后由列表的第二个元素执行排序,那么如何按键对词典进行排序?

如果有两个
列表包含: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);
var x=newdictionary()
{
{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)。选择(kvp=>kvp.Value);

如果有两个
列表包含: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);
var x=newdictionary()
{
{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)。选择(kvp=>kvp.Value);

如果您确实需要将其设置为当前设置,则此功能有效(测试代码,需要对其进行调整)。它类似于原始答案,它只做完整的列表(假设最多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());
        }
    }

如果您真的需要它作为您当前的设置,这是有效的(测试代码,它将需要调整)。它类似于原始答案,它只做完整的列表(假设最多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());
        }
    }

要使用列表作为字典的键,可以执行以下操作

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);
    }
公共类字典目录列表{
公共列表Lst{get;set;}
公共覆盖布尔等于(对象otherObj){
var otherList=otherObj as DictionaryKeyList;
return!this.Lst.Zip(otherList,(a,b)=>a==b).Any(x=>!x);
}
然后使用字典作为输入

Dictionary<DictionaryKeyList, string> dictData;
字典数据;

要使用列表作为字典的键,可以执行以下操作

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);
    }
公共类字典目录列表{
公共列表Lst{get;set;}
公共覆盖布尔等于(对象otherObj){
var otherList=otherObj as DictionaryKeyList;
return!this.Lst.Zip(otherList,(a,b)=>a==b).Any(x=>!x);
}
然后使用字典作为输入

Dictionary<DictionaryKeyList, string> dictData;
字典数据;

我强烈建议不要在字典上使用
列表
作为键如果键是一个数字并且需要这样对待,为什么要使用字符串列表?除了不使用列表作为字典键之外:如果你真的需要,你可以将
排序字典
与自定义比较器一起使用?我强烈建议不要使用我们将
列表
作为字典上的键如果该键是一个数字并且需要这样处理,为什么要使用字符串列表?除了不将列表用作字典键之外:如果确实需要,您可以使用带有自定义比较器的
SortedDictionary