天道酬勤,学无止境

Case-INsensitive Dictionary with string key-type in C#

If I have a Dictionary<String,...> is it possible to make methods like ContainsKey case-insensitive?

This seemed related, but I didn't understand it properly: c# Dictionary: making the Key case-insensitive through declarations

评论

This seemed related, but I didn't understand it properly: c# Dictionary: making the Key case-insensitive through declarations

It is indeed related. The solution is to tell the dictionary instance not to use the standard string compare method (which is case sensitive) but rather to use a case insensitive one. This is done using the appropriate constructor:

var dict = new Dictionary<string, YourClass>(
        StringComparer.InvariantCultureIgnoreCase);

The constructor expects an IEqualityComparer which tells the dictionary how to compare keys.

StringComparer.InvariantCultureIgnoreCase gives you an IEqualityComparer instance which compares strings in a case-insensitive manner.

var myDic = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
myDic.Add("HeLlo", "hi");

if (myDic.ContainsKey("hello"))
    Console.WriteLine(myDic["hello"]);

There are few chances where your deal with dictionary which is pulled from 3rd party or external dll. Using linq

YourDictionary.Any(i => i.KeyName.ToLower().Contains("yourstring")))

If you have no control in the instance creation, let say your object is desterilized from json etc, you can create a wrapper class that inherits from dictionary class.

public class CaseInSensitiveDictionary<TValue> : Dictionary<string, TValue>
{
    public CaseInSensitiveDictionary() : base(StringComparer.OrdinalIgnoreCase){}
}

I just ran into the same kind of trouble where I needed a caseINsensitive dictionary in a ASP.NET Core controller.

I wrote an extension method which does the trick. Maybe this can be helpful for others as well...

public static IDictionary<string, TValue> ConvertToCaseInSensitive<TValue>(this IDictionary<string, TValue> dictionary)
{
    var resultDictionary = new Dictionary<string, TValue>(StringComparer.InvariantCultureIgnoreCase);
    foreach (var (key, value) in dictionary)
    {
        resultDictionary.Add(key, value);
    }

    dictionary = resultDictionary;
    return dictionary;
}

To use the extension method:

myDictionary.ConvertToCaseInSensitive();

Then get a value from the dictionary with:

myDictionary.ContainsKey("TheKeyWhichIsNotCaseSensitiveAnymore!");

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Deserialize Dictionary<string, object> with enum values in C#
    I am trying to serialize/deserialize a Dictionary<string, object> in C#. Object can be anything that is serializable. Json.NET almost works, but if a value within the dictionary is an enum, the deserialization is not correct, as it gets deserialized as a long. TypeNameHandling.All does not make any difference. Is there any other fast solution to serialization library. The result does not have to be JSON, but must be text. I also have no influence on the data that is passed to the dictionary. I just have to serialize and deserialize anything that comes into my way. EDIT: StringEnumConverter
  • C# String replace with dictionary
    I have a string on which I need to do some replacements. I have a Dictionary<string, string> where I have search-replace pairs defined. I have created following extension methods to perform this operation: public static string Replace(this string str, Dictionary<string, string> dict) { StringBuilder sb = new StringBuilder(str); return sb.Replace(dict).ToString(); } public static StringBuild Replace(this StringBuilder sb, Dictionary<string, string> dict) { foreach (KeyValuePair<string, string> replacement in dict) { sb.Replace(replacement.Key, replacement.Value); } return sb; } Is there a
  • Upper vs Lower Case
    When doing case-insensitive comparisons, is it more efficient to convert the string to upper case or lower case? Does it even matter? It is suggested in this SO post that C# is more efficient with ToUpper because "Microsoft optimized it that way." But I've also read this argument that converting ToLower vs. ToUpper depends on what your strings contain more of, and that typically strings contain more lower case characters which makes ToLower more efficient. In particular, I would like to know: Is there a way to optimize ToUpper or ToLower such that one is faster than the other? Is it faster to
  • Proper way to initialize a C# dictionary with values?
    I am creating a dictionary in a C# file with the following code: private readonly Dictionary<string, XlFileFormat> FILE_TYPE_DICT = new Dictionary<string, XlFileFormat> { {"csv", XlFileFormat.xlCSV}, {"html", XlFileFormat.xlHtml} }; There is a red line under new with the error: Feature 'collection initilializer' cannot be used because it is not part of the ISO-2 C# language specification Can anyone explain what is going on here? I am using .NET version 2.
  • Map two lists into a dictionary in C#
    Given two IEnumerables of the same size, how can I convert it to a Dictionary using Linq? IEnumerable<string> keys = new List<string>() { "A", "B", "C" }; IEnumerable<string> values = new List<string>() { "Val A", "Val B", "Val C" }; var dictionary = /* Linq ? */; And the expected output is: A: Val A B: Val B C: Val C I wonder if there is some simple way to achieve it. And should I be worried about performance? What if I have large collections? I don't if there is an easier way to do it, currently I'm doing like this: I have an Extension method that will loop the IEnumerable providing me the
  • C# JSON Serialization of Dictionary into {key:value, …} instead of {key:key, value:value, …}
    Is it possible to serialize a .Net Dictionary<Key,Value> into JSON with DataContractJsonSerializer that is of the format: { key0:value0, key1:value1, ... } I use Dictionary <K,V>, because there is not predefined structure of the inputs. I'm interesting just for DataContractJsonSerializer result! I've already found a "Surrogate" example, but there is an additional "data" in the output, and if the dictionary <K, String> is, the escaping is false too. I've found the solution, what a needed! First of all, a serializable "dictionary" class: (Of course, this sample works just in one way, but I dont
  • Passing dynamic object to C# method changes return type
    I created a class that inherits DynamicObject and want to create a static method that can create new instances with pre-determined properties (stored in the Dictionary). public class CustomDynamic : DynamicObject { protected Dictionary<string, object> InnerDictionary; public static T Create<T>(Dictionary<string, object> dictionary) where T : CustomDynamic , new() { return new T { InnerDictionary = dictionary }; } } Usage: dynamic d = new Dictionary<string, object>(); var realPlayer = CustomDynamic.Create<Player>(d as Dictionary<string, object>); var dynaPlayer = CustomDynamic.Create<Player>(d)
  • How do C# Events work behind the scenes?
    I'm using C#, .NET 3.5. I understand how to utilize events, how to declare them in my class, how to hook them from somewhere else, etc. A contrived example: public class MyList { private List<string> m_Strings = new List<string>(); public EventHandler<EventArgs> ElementAddedEvent; public void Add(string value) { m_Strings.Add(value); if (ElementAddedEvent != null) ElementAddedEvent(value, EventArgs.Empty); } } [TestClass] public class TestMyList { private bool m_Fired = false; [TestMethod] public void TestEvents() { MyList tmp = new MyList(); tmp.ElementAddedEvent += new EventHandler<EventArgs
  • Explicitly freeing memory in c#
    I've create a c# application which uses up 150mb of memory (private bytes), mainly due to a big dictionary: Dictionary<string, int> Txns = new Dictionary<string, int>(); I was wondering how to free this memory up. I've tried this: Txns = null; GC.Collect(); But it doesn't seem to make much of a dent in my private bytes - they drop from say 155mb to 145mb. Any clues? Thanks -edit- Okay I'm having more luck with this code (it gets the private bytes down to 50mb), but why? Txns.Clear(); // <- makes all the difference Txns = null; GC.Collect(); -edit- Okay for everyone who says 'don't use GC
  • C#字典一键很多值(c# dictionary one key many values)
    问题 我想创建一个数据存储以允许我存储一些数据。 第一个想法是创建一个字典,在该字典中您拥有一个带有多个值的键,因此有点像一对多的关系。 我认为字典只有1个键值。 我还能如何存储此信息? 回答1 从.net3.5 + Dictionary<IKey, List<IValue>>您可以使用Linq名称空间中的Lookup来代替使用Dictionary<IKey, List<IValue>> 。 // lookup Order by payment status (1:m) // would need something like Dictionary<Boolean, IEnumerable<Order>> orderIdByIsPayed ILookup<Boolean, Order> byPayment = orderList.ToLookup(o => o.IsPayed); IEnumerable<Order> payedOrders = byPayment[false]; 来自msdn: 查找类似于字典。 不同之处在于,字典将键映射到单个值,而查阅将键映射到值的集合。 您可以通过在实现IEnumerable的对象上调用ToLookup来创建Lookup的实例。 您可能还想阅读有关相关问题的答案。 有关更多信息,请咨询msdn。 完整示例: using System
  • Dynamically Add C# Properties at Runtime
    I know there are some questions that address this, but the answers usually follow along the lines of recommending a Dictionary or Collection of parameters, which doesn't work in my situation. I am using a library that works through reflection to do lots of clever things with objects with properties. This works with defined classes, as well as dynamic classes. I need to take this one step further and do something along these lines: public static object GetDynamicObject(Dictionary<string,object> properties) { var myObject = new object(); foreach (var property in properties) { //This next line
  • 在C#中合并字典(Merging dictionaries in C#)
    问题 在C#中合并2个或更多词典( Dictionary<T1,T2> )的最佳方法是什么? (像LINQ这样的3.0功能很好)。 我正在考虑以下方法签名: public static Dictionary<TKey,TValue> Merge<TKey,TValue>(Dictionary<TKey,TValue>[] dictionaries); 或者 public static Dictionary<TKey,TValue> Merge<TKey,TValue>(IEnumerable<Dictionary<TKey,TValue>> dictionaries); 编辑:从Jare​​dPar和Jon Skeet得到了一个很酷的解决方案,但是我在想一些处理重复键的方法。 在发生冲突的情况下,只要保持一致,就可以将哪个值保存到字典中。 回答1 这部分取决于您遇到重复时要发生的情况。 例如,您可以执行以下操作: var result = dictionaries.SelectMany(dict => dict) .ToDictionary(pair => pair.Key, pair => pair.Value); 如果您得到任何重复的密钥,将抛出异常。 编辑:如果您使用ToLookup,那么您将获得一个查询,该查询每个键可以具有多个值。 然后,您可以将其转换为字典: var
  • 在运行时动态添加C#属性(Dynamically Add C# Properties at Runtime)
    问题 我知道有一些问题可以解决这个问题,但是答案通常遵循推荐字典或参数集合的方式,这在我的情况下不起作用。 我正在使用一个通过反射工作的库,以对具有属性的对象做很多聪明的事情。 这适用于定义的类以及动态类。 我需要进一步迈出一步,并按照以下方针做点事情: public static object GetDynamicObject(Dictionary<string,object> properties) { var myObject = new object(); foreach (var property in properties) { //This next line obviously doesn't work... myObject.AddProperty(property.Key,property.Value); } return myObject; } public void Main() { var properties = new Dictionary<string,object>(); properties.Add("Property1",aCustomClassInstance); properties.Add("Property2","TestString2"); var myObject = GetDynamicObject(properties); /
  • Field Initializer in C# Class not Run when Deserializing
    I have a class that defines a protected field. The protected field has a field initializer. When I deserialize the concrete class, the field initializer is not run. Why? What is the best pattern to solve the problem? If I move the initialization into a constructor, the constructor is also not invoked. [DataContract] public class MyConcrete { // FIELD INITIALIZER DOES NOT RUN WHEN COMMENTED IN: protected readonly Dictionary<int, string> myDict;// = new Dictionary<int, string>(); public MyConcrete() { myDict = new Dictionary<int, string>(); } private bool MyMethod(int key) { return myDict
  • Case-insensitive search
    I'm trying to get a case-insensitive search with two strings in JavaScript working. Normally it would be like this: var string="Stackoverflow is the BEST"; var result= string.search(/best/i); alert(result); The /i flag would be for case-insensitive. But I need to search for a second string; without the flag it works perfect: var string="Stackoverflow is the BEST"; var searchstring="best"; var result= string.search(searchstring); alert(result); If I add the /i flag to the above example it would search for searchstring and not for what is in the variable "searchstring" (next example not working)
  • C# dictionary value clearing out when I clear list previously assigned to it…why?
    Dictionary <string, List <SaleItem>> saleItemNew = new Dictionary<string, List< SaleItem>> (); saleItems = new List <SaleItem> (); saleItemNew.Add("1", saleItems); At this point the list in the Dictionary has values. saleItems.Clear(); However, when I clear out the list previously assigned to it, the dictionary's value List is now empty...why?
  • Best way to store data locally in .NET (C#)
    I'm writing an application that takes user data and stores it locally for use later. The application will be started and stopped fairly often, and I'd like to make it save/load the data on application start/end. It'd be fairly straightforward if I used flat files, as the data doesn't really need to be secured (it'll only be stored on this PC). The options I believe are thus: Flat files XML SQL DB Flat files require a bit more effort to maintain (no built in classes like with XML), however I haven't used XML before, and SQL seems like overkill for this relatively easy task. Are there any other
  • Hashtable with MultiDimensional Key in C#
    I'm basically looking for a way to access a hashtable value using a two-dimensional typed key in c#. Eventually I would be able to do something like this HashTable[1][false] = 5; int a = HashTable[1][false]; //a = 5 This is what I've been trying...hasn't worked Hashtable test = new Hashtable(); test.Add(new Dictionary<int, bool>() { { 1, true } }, 555); Dictionary<int, bool> temp = new Dictionary<int, bool>() {{1, true}}; string testz = test[temp].ToString();
  • How to parse case-insensitive strings with jsr310 DateTimeFormatter?
    jsr-310 has a handy class DateTimeFormatters which allows you to construct a DateTimeFormatter. I particularly like the pattern(String) method - see javadoc However, I hit a problem whereby this is case sensitive -- e.g. DateTimeFormatters.pattern("dd-MMM-yyyy"); matches with "01-Jan-2012", but not with "01-JAN-2012" or "01-jan-2012". One approach would be to break the string down and parse components, or another would be to use Regex to replace the case-insensitive strings with the case-sensitive string. But it feels like there ought to be an easier way...
  • C#中的命名字符串格式(Named string formatting in C#)
    问题 有什么方法可以通过名称而不是在C#中的位置来格式化字符串? 在python中,我可以执行以下示例(从这里无耻地被盗): >>> print '%(language)s has %(#)03d quote types.' % \ {'language': "Python", "#": 2} Python has 002 quote types. 在C#中有什么方法可以做到这一点? 例如说: String.Format("{some_variable}: {some_other_variable}", ...); 能够使用变量名来做到这一点会很好,但是字典也是可以接受的。 回答1 没有内置的方法来处理此问题。 这是一种方法 string myString = "{foo} is {bar} and {yadi} is {yada}".Inject(o); 这是另一个 Status.Text = "{UserName} last logged in at {LastLoginDate}".FormatWith(user); 第三种改进的方法,部分基于上述两种方法,来自Phil Haack 回答2 我有一个刚刚发布到我的博客的实现:http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing