按照数组列表中的顺序按关键字对字典进行排序
本文关键字:字典 排序 关键字 顺序 数组 列表 | 更新日期: 2023-09-27 17:59:49
在一次采访中,我被问到以下问题。如何按照数组列表中的顺序按关键字对字典进行排序。
例如,我有一本字典如下
Dictionary<string, string> stringDict = new Dictionary<string, string>();
stringDict.Add("1", "One");
stringDict.Add("7", "Seven");
stringDict.Add("6", "Six");
stringDict.Add("2", "Two");
stringDict.Add("3", "Three");
stringDict.Add("5", "Five");
stringDict.Add("4", "Four");
数组列表如下
ArrayList stringArList = new ArrayList();
stringArList.Add("1");
stringArList.Add("2");
stringArList.Add("3");
stringArList.Add("5");
stringArList.Add("6");
stringArList.Add("7");
stringArList.Add("4");
如何按字典在数组列表中的顺序对其进行排序?
你不能对字典本身进行排序,但你可以将键值对提取为列表,并对那些进行排序:
IEnumerable<KeyValuePair<string, string>> pairs =
stringDict.OrderBy(kvp => stringArList.IndexOf(kvp.Key));
但是,没有办法以任何特定的顺序"遍历"字典项。
您可以创建SortedDictionary
并提供IComparer<string>
var d = new SortedDictionary<string, string>(stringDict,
new PositionComparer(stringArList));
Comparer
实现为:
public class PositionComparer : IComparer<string>
{
private ArrayList Keys {get; set;}
public PositionComparer(ArrayList keys)
{
Keys = keys;
}
public int Compare(string s1, string s2)
{
return Keys.IndexOf(s1).CompareTo(Keys.IndexOf(s2));
}
}
这将生成一个按需要排序的值列表。
var sortedValues = stringDict.OrderBy(pair => stringArList.IndexOf(pair.Key))
.Select(pair => pair.Value)
.ToList();
正如前面在这个问题中多次提到的,C#Dictionary
无法排序。这是实施过程中固有的。正如您在这里所读到的,字典是使用哈希表实现的。这意味着这些商品没有任何订单。你不能说"把这本字典的第一个元素给我"。根本没有第一个、第二个或最后一个元素。关于字典中的元素,你只能说它有一个唯一的标识符,这个标识符决定了它在字典中的位置(通过散列函数的一点帮助)。
例如,当array
中有一个元素时,可以说"这个元素是下一个元素"或"这个元素就是上一个元素。"。数组中的每个元素都有上一个和下一个。这不适用于词典。
当你在字典中插入一个条目时,它会根据关键字生成一个散列(一个相当唯一的数字)。例如,由名称组成的密钥的一个非常简单(而且很糟糕)的散列是将每个字符的总和作为名称中的ASCII值,然后将它们相加。结果是一个数字,比如5,然后我们将该值插入位置5的存储(例如数组)中。但是,如果位置5是另一个值,恰好具有相同的散列结果,则您有一个collision
。如何解决这些问题,以及如何避免这些问题,就是哈希表的全部内容。有关此方面的详细信息,请参阅Wiki。
当您使用密钥someName
请求您的值时,它会对该值进行散列并在该位置查找它。
哈希表并不像我刚才解释的那么简单,它也有很多。你可以在Wiki上阅读更多。
因此,"对这个字典排序"的答案肯定是"不可以。"。但是,你可以将它转换为一个可排序的数据结构,比如列表,或者其他什么,然后对它进行排序。
我回答了以下问题。
var list = from arElement in stringArList.ToArray().ToList()
join dict in stringDict on arElement equals dict.Key
select dict ;
但面试官似乎对此不以为然。
original_dic.OrderBy
返回IOrderedEnumerable
,您可以将其转换为新字典。
var ordered_dic = original_dic.OrderBy(x => x.Key).ToDictionary(x=> x.Key, x=> x.Value);