我有一个像C#的字典
Dictionary<Person, int>
我想那种字典到位相对于键(在Person类的字段)。我该怎么做?互联网上所有可用的帮助都是列表的帮助,没有字典到位排序的特定示例。任何帮助将不胜感激!
我有一个像C#的字典
Dictionary<Person, int>
我想那种字典到位相对于键(在Person类的字段)。我该怎么做?互联网上所有可用的帮助都是列表的帮助,没有字典到位排序的特定示例。任何帮助将不胜感激!
Answers:
您无法排序Dictionary<TKey, TValue>
-本质上是无序的。(或者,检索条目的顺序是特定于实现的。您不应该依赖于版本之间以相同的方式工作,因为顺序并不是其设计功能的一部分。)
您可以使用SortedList<TKey, TValue>
或SortedDictionary<TKey, TValue>
,这两种方式均按键排序(如果将传递IEqualityComparer<T>
给构造函数,则以可配置的方式)-可能对您有用吗?
很少注意名称中的“列表”一词 SortedList
-它仍然是字典,因为它将键映射到值。它的实现使用列表内,有效地-因此,而不是通过哈希码往上看,它确实二进制搜索。SortedDictionary
类似地基于二进制搜索,但是通过树而不是列表。
SortedList<K,V>
:如果您建立了一个很大的列表(假设这些项目未预先排序),它将非常慢。通常,您应该改SortedDictionary<K,V>
而使用,或者使用第三方BDictionary<K,V>
来获得类似的性能,SortedDictionary
而又不会失去通过索引或“查找最近的键”来访问项目的能力。
var array = dict.Keys.ToArray(); array.Sort();
已经说明了正确的答案(只需使用SortedDictionary)。
但是,如果偶然需要将您的收藏集保留为Dictionary,则可以按有序的方式访问Dictionary键,例如,通过排序列表中的键,然后使用此列表来访问Dictionary。一个例子...
Dictionary<string, int> dupcheck = new Dictionary<string, int>();
...一些代码填写“ dupcheck”,然后...
if (dupcheck.Count > 0) {
Console.WriteLine("\ndupcheck (count: {0})\n----", dupcheck.Count);
var keys_sorted = dupcheck.Keys.ToList();
keys_sorted.Sort();
foreach (var k in keys_sorted) {
Console.WriteLine("{0} = {1}", k, dupcheck[k]);
}
}
不要忘记using System.Linq;
这一点。
var keys_sorted = dupcheck.Keys.ToList(); keys_sorted.Sort();
-简单的是keys_sorted = dupcheck.Keys.OrderBy(k => k).ToList();
...如果你要使用的值,然后就foreach (var ent in dupcheck.OrderBy(kv => kv.Key)) Console.WriteLine($"{ent.Key} = {ent.Value}");
当Dictionary被实现为哈希表时,SortedDictionary被实现为红黑树。
如果您没有利用算法中的顺序,而只需要在输出之前对数据进行排序,那么使用SortedDictionary会对性能产生负面影响。
您可以像这样对字典进行“排序”:
Dictionary<string, int> dictionary = new Dictionary<string, int>();
// algorithm
return new SortedDictionary<string, int>(dictionary);
dictionary.OrderBy(kv => kv.Key)
由于这个答案,搜索排名很高,我认为值得展示LINQ OrderBy解决方案:
class Person
{
public Person(string firstname, string lastname)
{
FirstName = firstname;
LastName = lastname;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
static void Main(string[] args)
{
Dictionary<Person, int> People = new Dictionary<Person, int>();
People.Add(new Person("John", "Doe"), 1);
People.Add(new Person("Mary", "Poe"), 2);
People.Add(new Person("Richard", "Roe"), 3);
People.Add(new Person("Anne", "Roe"), 4);
People.Add(new Person("Mark", "Moe"), 5);
People.Add(new Person("Larry", "Loe"), 6);
People.Add(new Person("Jane", "Doe"), 7);
foreach (KeyValuePair<Person, int> person in People.OrderBy(i => i.Key.LastName))
{
Debug.WriteLine(person.Key.LastName + ", " + person.Key.FirstName + " - Id: " + person.Value.ToString());
}
}
输出:
Doe, John - Id: 1
Doe, Jane - Id: 7
Loe, Larry - Id: 6
Moe, Mark - Id: 5
Poe, Mary - Id: 2
Roe, Richard - Id: 3
Roe, Anne - Id: 4
在此示例中,还可以对名字使用ThenBy:
foreach (KeyValuePair<Person, int> person in People.OrderBy(i => i.Key.LastName).ThenBy(i => i.Key.FirstName))
然后输出是:
Doe, Jane - Id: 7
Doe, John - Id: 1
Loe, Larry - Id: 6
Moe, Mark - Id: 5
Poe, Mary - Id: 2
Roe, Anne - Id: 4
Roe, Richard - Id: 3
LINQ还为需要它的人提供了OrderByDescending和ThenByDescending。