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

C# 是否可以对字典字符串键进行部分字符串匹配?,c#,dictionary,containers,C#,Dictionary,Containers,我的代码中有一本字典,我正在以以下方式使用它: Key Values 2011-07-15 1, 2, 3 2011-07-20 4, 5, 6 2010-02-11 7, 8, 9 我的代码需要能够查询与键中特定子字符串匹配的所有值。例如,如果我有子字符串2011-07,它应该返回值{1,2,3,4,5,6}。11的子字符串应返回1-9中的所有ID 有人能推荐一种简洁的方法来实现这一点吗?或者为检索这些信息提供更好的数据结构?一种简洁的方法是使用多值

我的代码中有一本
字典
,我正在以以下方式使用它:

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


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

一种简洁的方法是使用多值映射

例如:

Dictionary<string, Dictionary<string, List<int>>

如果您需要年/月/日,则需要多级词典。或者您也可以使用

如果字典内部使用散列,您就倒霉了,因为相似的字符串产生不同的散列。我只是在周末用C实现了这个要求的解决方案,一个面试测试/家庭作业。我使用了一个排序数组作为底层结构-昂贵的插入,但快速查找(使用二进制搜索)。要查找所有键以前缀开头的条目,我将查找第一个,然后只需转到下一个,下一个。。。对于一般子字符串,即不只是前缀,我的解决方案将不起作用。目前,我不知道对“常规子字符串”搜索有什么建议。

您可以有三本词典。年,月,日

请注意,将项目添加到三个词典时,不会复制这些项目

使用两个键拉出项时,可以使用LINQ扩展方法Intersect()获取与两个键匹配的项(在两个结果集上使用Intersect)


注意,这样做不会产生执行最快的代码。

我会使用扩展方法:

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

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

myDictionary.Where(kvp=>kvp.Key.Contains(“11”))。选择many(kvp=>kvp.Value)


你必须在所有的键中搜索一个广义的子串,而不需要一些很酷的魔法(不是.Net提供的),所以LINQ在这里不会对您造成太大的伤害。

您的建议对我的第二个示例没有帮助-我希望能够提供任何子字符串-它不一定需要在年/月/日整齐地断开。如果您想要年、月、日,您将需要多个级别的字典。我认为使用tree将比这更快。如果您共享子节点,那么就不必执行linq操作。您不需要遍历树几次来收集匹配的节点吗?这必须加起来。在第二次编辑中,如果你传递一个适当的比较器方法,你可以有一个int类型的字典键,并说43部分匹配343756。我认为下面的各种答案表明人们对“子字符串”的含义有不同的假设。从您对11的评论中,我假设您指的是一个真正通用的子字符串,它不一定是前缀、后缀,只是一个[year | month | day],也不是正则表达式?@J Trana-您是对的,我指的是一个真正通用的子字符串。@LeopardSkinPillBoxHat,您可以发布您最终的解决方案吗?SortedDictionary应该很容易实现此功能,但它仍然不是。(?)Java有。
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;
    }
}
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;
}
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;
}