是否可以对Dictionary字符串键进行部分字符串匹配?

Leo*_*Hat 15 c# containers dictionary

Dictionary<string, List<int>>在我的代码中有一个我以下面的方式使用:

Key           Values  
2011-07-15    1, 2, 3
2011-07-20    4, 5, 6
2010-02-11    7, 8, 9
Run Code Online (Sandbox Code Playgroud)

我的代码需要能够查询匹配键中特定子字符串的所有值.例如,如果我有子字符串,2011-07它应该返回值{1, 2, 3, 4, 5, 6}.子字符串11应返回所有ID 1-9.

有人可以推荐一种简洁的方法来实现这一目标吗?或者提供更好的数据结构来检索这些信息?

Tip*_*ipx 9

我会做一个扩展方法:

public static class DictionaryExt
{
    public static IEnumerable<T> PartialMatch<T>(this Dictionary<string, T> dictionary, string partialKey)
    {
        // This, or use a RegEx or whatever.
        IEnumerable<string> fullMatchingKeys = 
            dictionary.Keys.Where(currentKey => currentKey.Contains(partialKey));

        List<T> returnedValues = new List<T>();

        foreach (string currentKey in fullMatchingKeys)
        {
            returnedValues.Add(dictionary[currentKey]);
        }

        return returnedValues;
    }
}
Run Code Online (Sandbox Code Playgroud)

将值添加到字典中的"成本"不会改变,但是检索的成本会更高,但只有当您知道自己正在进行部分匹配时.

顺便说一句,我相信你可以在一个Lambda表达式中改变它,但概念保持不变.

编辑:在您的示例中,此方法将返回2个值列表,但您可以更改它以合并列表.这是您可以执行的扩展方法:

public static IEnumerable<T> PartialMatch<T>(
    this Dictionary<string, IEnumerable<T>> dictionary,
    string partialKey)
{
    // This, or use a RegEx or whatever.
    IEnumerable<string> fullMatchingKeys = 
        dictionary.Keys.Where(currentKey => currentKey.Contains(partialKey));

    List<T> returnedValues = new List<T>();

    foreach (string currentKey in fullMatchingKeys)
    {
        returnedValues.AddRange(dictionary[currentKey]);
    }

    return returnedValues;
}
Run Code Online (Sandbox Code Playgroud)

编辑2:想想它,你也可以使它更通用.使用下一个扩展方法,它可以在任何字典上工作,只要你提供一个comparer检查"部分匹配"的意思:

public static IEnumerable<TValue> PartialMatch<TKey, TValue>(
    this Dictionary<TKey, IEnumerable<TValue>> dictionary,
    TKey partialKey,
    Func<TKey, TKey, bool> comparer)
{
    // This, or use a RegEx or whatever.
    IEnumerable<TKey> fullMatchingKeys = 
        dictionary.Keys.Where(currentKey => comparer(partialKey, currentKey));

    List<TValue> returnedValues = new List<TValue>();

    foreach (TKey currentKey in fullMatchingKeys)
    {
        returnedValues.AddRange(dictionary[currentKey]);
    }

    return returnedValues;
}
Run Code Online (Sandbox Code Playgroud)


J T*_*ana 5

您正在寻找简洁的答案。如果没有对文本进行低级索引(我不知道任何专门的 .Net 类),我认为字典仍然是你最好的选择。查询类似:

myDictionary.Where(kvp => kvp.Key.Contains("11")).SelectMany(kvp => kvp.Value);

无论如何,您必须在没有一些非常酷的魔法(不是由 .Net 提供)的情况下搜索所有键以获取通用子字符串,因此 LINQ 在这里不会对您造成太大伤害。