首页 > 解决方案 > C# 根据字符串列表对字典进行排序?

问题描述

我有以下列表(忽略 LST ==> 部分):

LST ==>Username
LST ==>Password
LST ==>SampleRequestValue
LST ==>SampleComplexRequest
LST ==>SampleComplexRequest.SampleTestBValue
LST ==>SampleComplexRequest.SampleTestAValue

以及字典中的以下键列表(忽略 DICT ==> 部分):

DICT ==>Password
DICT ==>Username
DICT ==>SampleRequestValue
DICT ==>SampleComplexRequest.SampleTestAValue
DICT ==>SampleComplexRequest.SampleTestBValue

我希望字典按列表的顺序排序(即密码前的用户名)。

在 SO 上看到了一些示例 / 有点 / 不是这个的真正例子......但不是真正类似的场景。还希望它尽可能快,而不是蛮力强迫它。

LST 可能有比 DICT 更多的项目。我只关心排序 DICT。DICT 将始终在 LST 中具有匹配的条目。我只想要 LST 订单的 DICT。

标签: c#.net

解决方案


另一种方法是编写一个小的自定义比较器类,它使用列表来确定比较值:

public class ListComparer : IComparer<string>
{
    public List<string> ComparisonList { get; set; }

    public ListComparer(List<string> comparisonList)
    {
        ComparisonList = comparisonList;
    }

    public int Compare(string x, string y)
    {
        if (ComparisonList == null || !ComparisonList.Contains(x))
            return 1;

        if (ComparisonList.Contains(y))
            return ComparisonList.IndexOf(x).CompareTo(ComparisonList.IndexOf(y));

        return -1;
    }
}

然后,您可以将其传递给SortedDictionary的构造函数,然后每次将项目添加到字典时都会使用它。这样,您不必OrderBy每次添加新值时都调用字典(这也具有每次创建全新字典的负面影响)。

这是一个可能有帮助的代码示例。请注意,我们首先添加“密码”,然后添加“用户名”,但是当我们输出项目时,它们的顺序是预期的:

static void Main()
{
    var comparisonList = new List<string>
    {
        "Username",
        "Password",
        "SampleRequestValue",
        "SampleComplexRequest",
        "SampleComplexRequest.SampleTestBValue",
        "SampleComplexRequest.SampleTestAValue",
    };

    // Add items in an "unorderd" order
    var items = new SortedDictionary<string, string>(new ListComparer(comparisonList))
    {
        {"Password", "LetMeIn"},
        {"Username", "JohnDoe"}
    };

    foreach (var item in items)
    {
        Console.WriteLine($"{item.Key} = {item.Value}");
    }

    GetKeyFromUser("\nDone! Press any key to exit...");
}

输出

在此处输入图像描述


我刚刚看到您无法控制初始字典,但愿意创建一个新字典。在这种情况下,您可以简单地使用接收字典和比较器的重载构造函数,它将自动在您的列表中排序:

 var sortedItems = new SortedDictionary<string, string>(
     originalDictionary, new ListComparer(comparisonList));

推荐阅读