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