【问题标题】:How to get original case key by case insensitive key in Dictionary<string, int>如何通过 Dictionary<string, int> 中不区分大小写的键获取原始大小写键
【发布时间】:2018-09-14 06:02:49
【问题描述】:

有字典:

var dictionary1 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
    {{"abc1", 1}, {"abC2", 2}, {"abc3", 3}};

我可以得到一个值:

var value = dictionary1["Abc2"];

如果搜索键"Abc2"我需要得到原始键"abC2"和值2。

如何通过不区分大小写的键获取原始大小写键?

【问题讨论】:

  • 为字典编写不区分大小写的索引
  • 我不认为字典是这样工作的。尝试不同的数据结构。
  • @SamvelPetrosov,将原始区分大小写的密钥放在哪里?
  • 尝试将原始键与值一起存储在类似Dictionary&lt;string, KeyValuePair&lt;string, int&gt;&gt; 的结构中。因此,您可以将值与原始键一起获得。
  • 明确一点,这是一件完全合理的事情,Dictionary 没有理由无法提供此功能。它只是没有:(

标签: c# dictionary case-insensitive


【解决方案1】:

很遗憾,你不能这样做。 Dictionary&lt;TKey, TValue&gt; 公开 bool TryGetEntry(TKey key, KeyValuePair&lt;TKey, TValue&gt; entry) 方法是完全合理的,但它没有这样做。

正如 cmets 中的 stop-cran 建议的那样,最简单的方法可能是让字典中的每个 value 都具有与字典中的键相同的键。所以:

var dictionary = new Dictionary<string, KeyValuePair<string, int>>(StringComparer.OrdinalIgnoreCase)
{
    // You'd normally write a helper method to avoid having to specify
    // the key twice, of course.
    {"abc1", new KeyValuePair<string, int>("abc1", 1)},
    {"abC2", new KeyValuePair<string, int>("abC2", 2)},
    {"abc3", new KeyValuePair<string, int>("abc3", 3)}
};
if (dictionary.TryGetValue("Abc2", out var entry))
{
    Console.WriteLine(entry.Key); // abC2
    Console.WriteLine(entry.Value); // 2
}
else
{
    Console.WriteLine("Key not found"); // We don't get here in this example
}

如果这是类中的一个字段,您可以编写辅助方法以使其更简单。您甚至可以围绕Dictionary 编写自己的包装类来实现IDictionary&lt;TKey, TValue&gt;,但添加一个额外的TryGetEntry 方法,这样调用者就不需要知道“内部”字典是什么样的。

【讨论】:

    【解决方案2】:

    即使大小写与键不匹配,您也可以使用以下利用 LINQ 的代码来获取字典键值对。

    注意:此代码可用于任何大小的字典,但它最适合较小大小的字典,因为 LINQ 基本上是一一检查每个键值对,而不是直接转到所需的键值对。

    Dictionary<string,int> dictionary1 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
    {
        {"abc1",1},
        {"abC2",2},
        {"abc3",3}
        } ;
    
    var value1 = dictionary1["ABC2"];//this gives 2, even though case of key does not macth
    
    //use LINQ to achieve your requirement
    var keyValuePair1 = dictionary1.SingleOrDefault (d => d.Key.Equals("Abc2", StringComparison.OrdinalIgnoreCase) );
    
    var key1 = keyValuePair1.Key ;//gives us abC2
    var value2 =keyValuePair1.Value;//gives us 2
    

    【讨论】:

    • 但这会将 O(1) 操作变成 O(n) 操作,使得使用字典相对没有意义。在非常小众的情况下可能没问题,但我通常假设如果使用字典,至少部分是为了避免 O(n) 查找。
    • 这是正确的,因为字典应该很快。但是如果字典很小呢?
    • 那么当然,它会起作用 - 但我认为 至少 应该非常突出地包含在答案中,因为它违背了使用字典的通常期望.
    • 感谢您提供的重要信息。我已将此作为注释添加到我的答案中。
    • @Sunil,正如 Daisy Shipton 所指出的,这对我来说毫无意义。这本词典的整个过程是网络请求,已经花费了 1 小时,这太长了。对于字典中的 100000 个项目,我需要它尽可能快。但对于简短的字典,它绝对有用。
    猜你喜欢
    • 1970-01-01
    • 2013-08-05
    • 2017-10-20
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多