如何按键对字典进行排序
本文关键字:排序 字典 何按键 | 更新日期: 2023-09-27 18:14:16
我有字典Dictionary<string, Point>
键是c1,c3,c2,t1, t4,t2我想把它们排序成c1,c2,c3,t1,t2,t3
我正在尝试使用
进行排序Input.OrderBy(key => key.Key );
但是它不起作用
知道怎么解决这个问题吗
Input.OrderBy
不对字典进行排序,它创建一个查询,以特定的顺序返回条目。
也许OrderedDictionary给了你想要的。
或者使用Generic SortedDictionary
将未排序的对象加载到SortedDictionary
对象中,如下所示:
var sortedCustomerData
= new SortedDictionary<string, string>(unsortedCustomerData);
其中unsortedCustomerData
是相同的泛型(Dictionary string, string
或在您的情况下string, point
)。它将自动按键
根据msdn: SortedDictionary<TKey, TValue>(IDictionary<TKey, TValue>)
:初始化SortedDictionary<TKey, TValue>
类的新实例,该实例包含从指定的IDictionary<TKey, TValue>
复制的元素,并使用默认的IComparer<T>
实现作为密钥类型
自输入。OrderBy创建一个查询,该查询以有序的顺序返回条目,只需将其分配给相同的字典。
objectDict = objectDict.OrderBy(obj => obj.Key).ToDictionary(obj => obj.Key, obj => obj.Value);
只是一个猜测,但它看起来像你假设它要排序输入。OrderBy方法实际上返回包含相同值的IOrderedEnumerable的有序实例。如果您想保留返回值,可以执行以下操作:
IOrderedEnumerable orderedInput
orderedInput = Input.OrderBy(key=>key.Key)
大多数修改集合的方法都遵循相同的模式。它这样做是为了不更改原始集合实例。这可以防止您在不打算更改实例时意外更改实例。如果您想只使用排序实例,那么只需将变量设置为方法的返回值,如上面所示。
下面的代码使用另外两个列表对字典进行排序。
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);
}
}
}
上述代码的输出如下所示:
c1 1 2
c2 4 5
c3 0 1
c4 3 4
t1 5 6
t2 6 7
t3 2 3
我用
var l = Input.OrderBy(key => key.Key);
并将其转换为Dictionary
这取决于你的需要。如果您需要以列表的形式输出键,那么一次性排序就可以了。我做了下面的测试,你可以运行,看看如何实现按键排序。
[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);
}
如果你需要你的键总是排序,我会使用SortedDictionary
。在下面,我使用旧字典作为参数的构造函数创建一个SortedDictionary
。您可以运行测试并验证结果。
[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);
}
与 0 (1)的Dictionary
相比, SortedDictionary
的插入和检索次数 0 (log n)。因此,如果只有一次或很少需要对元素进行排序,并且您经常插入和删除一次,那么排序将是您所需要的。
ok,检查一下,应该可以工作了
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();