简体   繁体   English

如何按键对字典进行排序

[英]How to sort a dictionary by key

I have dictionary Dictionary<string, Point>我有字典Dictionary<string, Point>

the Key is c1,c3,c2,t1,,t4,t2 I want to sort them to be c1,c2,c3,t1,t2,t3关键是 c1,c3,c2,t1,,t4,t2 我想将它们排序为 c1,c2,c3,t1,t2,t3

I'm trying to sort it using我正在尝试使用

Input.OrderBy(key => key.Key );

but it doesn't work但它不起作用

any idea how to solve that任何想法如何解决

Input.OrderBy does not sort the dictionary, it creates a query that returns the items in a specific order. Input.OrderBy不对字典进行排序,它会创建一个以特定顺序返回项目的查询。

Perhaps OrderedDictionary gives you what you want.也许OrderedDictionary给了你你想要的。

Or use the Generic SortedDictionary或者使用通用SortedDictionary

Load the unsorted object into a SortedDictionary object like so:将未排序的对象加载到 SortedDictionary 对象中,如下所示:

SortedDictionary<string, string> sortedCustomerData = new SortedDictionary<string,string>(unsortedCustomerData);

Where unsortedCustomerData is the same generic type (Dictionary string, string or in your case string, point).其中 unsortedCustomerData 是相同的通用类型(字典字符串、字符串或在您的情况下是字符串、点)。 It will automatically sort the new object by key它将自动按键对新对象进行排序

According to msdn: SortedDictionary(IDictionary): Initializes a new instance of the SortedDictionary class that contains elements copied from the specified IDictionary and uses the default IComparer implementation for the key type.根据 msdn:SortedDictionary(IDictionary):初始化 SortedDictionary 类的新实例,该类包含从指定的 IDictionary 复制的元素,并使用键类型的默认 IComparer 实现。

由于 Input.OrderBy 创建了一个以有序顺序返回项目的查询,只需将其分配给同一个字典。

objectDict = objectDict.OrderBy(obj => obj.Key).ToDictionary(obj => obj.Key, obj => obj.Value);

Just a guess but it looks like you are assuming it is going to sort Input.只是一个猜测,但看起来您假设它将对 Input 进行排序。 The OrderBy method actually returns an ordered instance of an IOrderedEnumerable containing the same values. OrderBy 方法实际上返回一个包含相同值的 IOrderedEnumerable 的有序实例。 If you want to keep the return value you can do the below:如果要保留返回值,可以执行以下操作:

IOrderedEnumerable orderedInput
orderedInput = Input.OrderBy(key=>key.Key)

Most methods that would modify the collection follow this same pattern.大多数修改集合的方法都遵循相同的模式。 It does this so that it is not changing the origional collection instance.它这样做是为了不更改原始集合实例。 This protects you from accidently changing the instance when you didn't intend to.这可以防止您在无意中意外更改实例。 If you do want to only use the sorted instance then you just set the variable to the return of the method as shown above.如果您只想使用已排序的实例,那么您只需将变量设置为方法的返回值,如上所示。

The following code uses two more list s to sort a dictionary.以下代码使用另外两个list 字典进行排序

using System;
using System.Collections.Generic;
using System.Drawing;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            Dictionary<string,Point> r=new Dictionary<string,Point>();
            r.Add("c3",new Point(0,1));
            r.Add("c1",new Point(1,2));
            r.Add("t3",new Point(2,3));
            r.Add("c4",new Point(3,4));
            r.Add("c2",new Point(4,5));
            r.Add("t1",new Point(5,6));
            r.Add("t2",new Point(6,7));
            // Create a list of keys
            List<string> zlk=new List<string>(r.Keys);
            // and then sort it.
            zlk.Sort();
            List<Point> zlv=new List<Point>();
            // Readd with the order.
            foreach(var item in zlk) {
                zlv.Add(r[item]);
            }
            r.Clear();
            for(int i=0;i<zlk.Count;i++) {
                r[zlk[i]]=zlv[i];
            }
            // test output
            foreach(var item in r.Keys) {
                Console.WriteLine(item+" "+r[item].X+" "+r[item].Y);
            }
            Console.ReadKey(true);
        }
    }
}

The output of the code above is shown below.上面代码的输出如下所示。

c1 1 2
c2 4 5
c3 0 1
c4 3 4
t1 5 6
t2 6 7
t3 2 3

It depends what your needs are.这取决于你的需求是什么。 If you need the keys out as a list a one time order by would work.如果您需要将密钥作为列表列出,则一次性订购将起作用。 I have made below test which you can run and see how to implement order by key.我做了下面的测试,你可以运行它,看看如何按键实现命令。

[Fact]
public void SortDict()
{
    // Arrange
    var initial = new Dictionary<string, bool>()
    {
        {"c1", true },
        {"c3", true },
        {"c2", true },
        {"t1", true },
        {"t3", true },
        {"t2", true },
    };
    var expected = new List<string>() { "c1", "c2", "c3", "t1", "t2", "t3" };

    // Act
    var actual = initial.OrderBy(k => k.Key).Select(k => k.Key)
        .ToList();

    // Assert
    actual.ShouldBeEquivalentTo(expected);
}

If you instead need your keys to always be sorted I would use a SortedDictionary .如果您需要始终对密钥进行排序,我将使用SortedDictionary In below I'm creating a SortedDictionary using its constructor with the old dictionary as parameter.在下面,我使用其构造函数创建一个SortedDictionary ,并将旧字典作为参数。 You can run the test and verify the result.您可以运行测试并验证结果。

[Fact]
public void SortDictUsingLinq()
{
    // Arrange
    var initial = new Dictionary<string, bool>()
    {
        {"c1", true },
        {"c3", true },
        {"c2", true },
        {"t1", true },
        {"t3", true },
        {"t2", true },
    };
    var expected = new List<string>() { "c1", "c2", "c3", "t1", "t2", "t3" };

    // Act
    var sortedDict = new SortedDictionary<string, bool>(initial);

    // Assert
    sortedDict.Keys.ToList().ShouldBeEquivalentTo(expected);
}

SortedDictionary has O(log n) insertion and retrieval times compared to Dictionary which has O(1) .与具有O(1)Dictionary相比, SortedDictionary具有O(log n)的插入和检索时间。 Hence if it is only once or rarely you need elements sorted and you insert and remove often one time sort would be what you need.因此,如果只有一次或很少需要对元素进行排序,并且您经常插入和删除一次排序将是您所需要的。

I used我用了

var l =  Input.OrderBy(key => key.Key);

and I converted it to Dictionary我把它转换成字典

ok check this it should work好的,检查一下它应该可以工作

var r = new Dictionary<string, Point>();
r.Add("c3", new Point(0, 0));
r.Add("c1", new Point(0, 0));
r.Add("t3", new Point(0, 0));
r.Add("c4", new Point(0, 0));
r.Add("c2", new Point(0, 0));
r.Add("t1", new Point(0, 0));
r.Add("t2", new Point(0, 0));
var l = r.OrderBy(key => key.Key);
var dic = l.ToDictionary((keyItem) => keyItem.Key, (valueItem) => valueItem.Value);

foreach (var item in dic)
{

    Console.WriteLine(item.Key);
}
Console.ReadLine();

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

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