按自定义 array/list 对 C# 字典进行排序,并将重新排序的字典值输出为列表

Sort C# Dictionary by a custom array/list, and output reordered dictionary Values as list

有几个类似的问题,但不幸的是 none 我发现它们提供了我需要的答案。感谢帮助。

第一个问题

我有一本字典可以这样说(例如简化版):

IDictionary<string, string> Beatles = new Dictionary<string, string>();
Beatles.Add("Singer", "John");
Beatles.Add("Drummer", "Ringo");
Beatles.Add("Guitar", "Paul");
Beatles.Add("Bass", "George");

是否可以根据字符串数组或下面的列表重新排序字典(编辑 - 并输出一个仅包含重新排序值的列表,因为有人澄清字典没有顺序):

string[] reorderList = {"Guitar","Bass","Singer","Drummer"};

编辑 - 我希望输出是包含以下命令的列表:“Paul”、“George”、“John”、“Ringo”



次要问题

假设我没有在我的订购字符串中包含字典项目之一,如下所示:

string[] locations = {"Guitar","Singer","Drummer"};

我希望所有缺失的项目(在本例中只是“Drums”)自动添加到末尾。这可能吗?

这是一个非常有趣的问题。首先,正如大家所建议的,你不能重新排序词典。 但是,您可以通过 运行 下面的一段代码

来实现您想要的输出
var pass1 = reorderList.Select(x => Beatles.ContainsKey(x) ? Beatles[x] : null).Where(x => x != null); //Adds desired ordered list of Dictionary values to the list
var result = pass1.Union(Beatles.Values.Except(pass1)).ToList(); //Appends remaining values, if any, to list

变量 result 将有您想要的输出。

更新

更新了上面的代码以处理无效值。

这是一个快速扩展,可以return满足您的要求:

    public static class DictionaryExtension
    {
        public static List<T> CustomSort<TK, T>(this IDictionary<TK, T> src, TK[] sortList)
        {
            // items in the sortList
            var output = (from key in sortList where src.ContainsKey(key) select src[key]).ToList();

            // remaining "other" items
            output.AddRange((from item in src where !sortList.Contains(item.Key) select item.Value).OrderBy(o => o));

            return output;
        }
    }

注意:它不检查 IComparable 所以 YMMV。如果您在 reorderList 中有重复的键,您将在结果中得到重复的值。