【问题标题】:Sorting a dictionary by keys in the order in an Arraylist按 Arraylist 中的顺序按键对字典进行排序
【发布时间】:2014-06-08 23:11:25
【问题描述】:

我在一次采访中被问到以下问题。如何按数组列表中的顺序对字典进行排序。

所以例如我有一个字典如下

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

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

【问题讨论】:

  • 嗯。我的回答是“字典没有订单”。如果他们因此不雇用我,我就会知道无论如何我都不想为他们工作。 :)
  • ...除非它是有序字典。
  • 我同意 D Stanley 的观点——这很可能是一个技巧问题。在我看来,这些面试问题真的已经过时了,需要用老式的“你能解决这个有效的问题吗?你会怎么做”编码时间来代替。像这样的问题是由有点高级的工程师提出来提高他们自己的自尊心的。 (我知道,因为我创造了很多……然后我意识到我不需要通过采访来提高我的自尊心……我真的很擅长我所做的事情,我的行为证明了证明我比我正在采访的人更聪明。)
  • “像这样的问题是由有点高级的工程师为了提高自己的自尊而创造的”我完全同意......
  • 今天早上早些时候提出了这个确切的问题。但是无法找到它。我以为@DStanley 确实回答了它

标签: c# dictionary arraylist


【解决方案1】:

好吧,你不能对字典本身进行排序,但你可以将键值对提取为一个列表并对那些进行排序:

IEnumerable<KeyValuePair<string, string>> pairs = 
    stringDict.OrderBy(kvp => stringArList.IndexOf(kvp.Key));

但没有办法以任何特定顺序“遍历”字典项。

您可以创建一个SortedDictionary 并提供一个IComparer&lt;string&gt;

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

    【讨论】:

      【解决方案3】:

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

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

      当您将一个项目插入字典时,它会根据键生成一个哈希(一个相当唯一的数字)。例如,由名称组成的键的非常简单(和错误)散列将取每个字符的总和作为名称中的 ASCII 值,然后将它们加在一起。结果是一个数字,比如 5,然后我们将值插入到位置 5 的存储(例如数组)中。但是,如果在位置 5 是另一个值,它恰好具有相同的哈希结果,您有一个 @ 987654325@。如何解决这些问题以及如何避免这些问题就是哈希表的全部意义所在。有关这方面的更多信息,请参阅 Wiki。

      当您使用您的键 someName 请求您的值时,它将对该值进行哈希处理并在该位置查找它。

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

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

      【讨论】:

        【解决方案4】:

        我的回答如下。

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

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

        【讨论】:

        • 您实际上并没有根据它们在数组列表中的位置对它们进行排序。
        • 好吧,我不确定你的意思,但我可以按数组列表中的顺序对其进行排序(而是创建一个新字典)。我运行它,它似乎工作正常。您能否详细说明为什么您认为这行不通?
        • 哦,好吧,我想我明白你的意思了。你是对的,我无法对原始字典进行排序。事实上,我问面试我的人他将如何解决这个问题,他是个笨蛋,他只是把一些我不清楚的事情闷住了,这也没有意义。很明显他也不知道正确的答案。
        • 这样的面试问题通常不是为了得到“正确答案”,而是为了看看你的想法。你如何处理这个问题?要么或试图通过羞辱受访者来提升面试官的自我:)
        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 2012-05-30
          • 2011-03-01
          • 2017-05-22
          • 2014-04-11
          • 2020-01-22
          • 2019-08-02
          • 1970-01-01
          • 2021-12-20
          • 2015-08-09
          相关资源
          最近更新 更多