按 Arraylist 中的键对字典进行排序

问题描述 投票:0回答:6

我在面试中被问到以下问题。如何按数组列表中的键对字典进行排序。

例如我有一本字典如下

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");

如何按照字典在数组列表中的顺序对字典进行排序?

c# dictionary arraylist
6个回答
3
投票

你无法对字典本身进行排序,但是你可以将键值对提取为列表并进行排序那些

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));
   }
}

2
投票

这将生成一个按要求排序的值列表。

var sortedValues = stringDict.OrderBy(pair => stringArList.IndexOf(pair.Key))
                             .Select(pair => pair.Value)
                             .ToList();

1
投票

正如之前在这个问题中多次说过的,C#

Dictionary
无法排序。这是实现所固有的。正如您可以在here阅读的那样,字典是使用哈希表实现的。这意味着这些项目没有任何顺序。你不能说“给我这本字典的第一个元素”。根本没有第一个、第二个或最后一个元素。关于字典中的元素,您唯一可以说的是它有一个唯一标识符,该标识符确定它在字典中的位置(在哈希函数的帮助下)。

例如,当

array
中有一个元素时,您可以说“此元素是下一个元素”或“此元素是上一个元素”。数组中的每个元素都有前一个和后一个。这不适用于字典。

当您将一个项目插入字典时,它将根据键生成一个哈希值(一个相当唯一的数字)。例如,由名称组成的键的非常简单(且不好)的散列将采用名称中作为其 ASCII 值表示的每个字符的总和,然后将它们加在一起。结果是一个数字,比如 5,那么我们会将该值插入存储(例如数组)中的位置 5。但是,如果位置 5 是另一个值,它恰好具有相同的哈希结果,则您将得到一个

 collision
。如何解决这些问题以及如何避免这些问题就是哈希表的全部内容。有关详细信息,请参阅 Wiki。

当您使用密钥请求值时

someName
,它将散列该值并在该位置查找它。

哈希表并不像我刚才解释的那么简单,它还有很多。您可以在 Wiki 上阅读更多内容。

所以“对这本字典进行排序”的答案绝对是“不行”。但是,您可以将其转换为可排序的数据结构,例如列表或其他任何内容,然后对其进行排序。


0
投票

我回复了以下答案。

  var list = from arElement in stringArList.ToArray().ToList()
                   join dict in stringDict on arElement equals dict.Key 
                   select dict ;

但是面试官似乎并没有留下深刻的印象。


0
投票

original_dic.OrderBy
返回
IOrderedEnumerable
,您可以将其转换为新字典。

var ordered_dic = original_dic.OrderBy(x => x.Key).ToDictionary(x=> x.Key, x=> x.Value);

0
投票

我正在使用它,如下所示:

stringDict = stringDict.OrderBy(x => stringArList.IndexOf(x.Key)).ToDictionary(x=>x.Key,x=>x.Value);
© www.soinside.com 2019 - 2024. All rights reserved.