当前位置: 首页 > 知识库问答 >
问题:

如何使用ValueTuples创建通用不区分大小写的多键字典?

拓拔骁
2023-03-14

我知道我可以用一个系统来定义字典。ValueTuple键(基于此答案)如下:

var multiKeyDictionary = new Dictionary<(int key1, string key2), object>()
{
    {(1, "test"), new object() }
};

但是,我希望在ValueTuple中存在的任何字符串值都被视为不区分大小写,使用IEqualityCompler或类似的用于字典访问的惯用方法,类似于这里的规定。

到目前为止,我想到的解决办法是:

  • 实现IEqualityComparer对于系统是必要的。元组
  • 按如下方式包装对词典的所有访问:
class InsensitiveValueTupleDictionary
{
    private Dictionary<(int key1, string key2), object> _multiKeyDictionary = new Dictionary<(int key1, string key2), object>();

    public void Add((int key1, string key2) key, object value)
    {
        _multiKeyDictionary.Add((key.key1, key.key2.ToLower()), value);
    }

    public bool ContainsKey((int key1, string key2) key)
    {
        return _multiKeyDictionary.ContainsKey((key.key1, key.key2.ToLower()));
    }

    // ... and so on
}

这两种策略都需要为ValueTuple的每个独特组合编写设置代码,例如(int,string)(string,int)(string,string,int),等等。

是否有另一种方法允许任意ValueTuple组合不区分大小写的密钥相等?

共有1个答案

齐永昌
2023-03-14

你在用元组把自己画进那个角落。元组代表的是一袋值,而不是一个实体。

您可以以元组友好的方式实现自己的密钥类型:

public struct Key : IEquatable<Key>
{
    private readonly int hashCode;

    public Key(int key1, string key2)
    {
        this.Key1 = key1;
        this.Key2 = key2;
        this.hashCode = HashCode.Combine(key1, StringComparer.OrdinalIgnoreCase.GetHashCode(Key2));
    }

    public int Key1 { get; }
    public string Key2 { get; }

    public bool Equals(Key other)
        => this.hashCode == other.hashCode
            && this.Key1 == other.Key1
            && string.Equals(this.Key2, other.Key2, StringComparison.OrdinalIgnoreCase);

    public override bool Equals(object obj)
        => obj is Key key && this.Equals(key);

    public override int GetHashCode() => this.hashCode;
    
    public static implicit operator (int key1, string key2)(Key key)
        => (key1: key.Key1, key2: key.Key2);
    
    public static implicit operator Key((int key1, string key2) key)
        => new Key(key.key1, key.key2);
    
    public void Deconstruct(out int key1, out string key2)
        => (key1, key2) = (this.Key1, this.Key2);
}

您甚至可以将其用于元组或“类似”元组:

var key = new Key(1, "one");
var (k1, k2) = key;
(int key1, string key2) t = key;
t.key1 = 2;
t.key2 = "two";
key = t;

如果您真的想继续使用元组,请定义自己的比较器:

public class MyTupleComparer : IEqualityComparer<(int key1, string key2)>
{
    public bool Equals((int key1, string key2) x, (int key1, string key2) y)
        => x.key1 == y.key1
            && string.Equals(x.key2, y.key2, StringComparison.OrdinalIgnoreCase);

    public int GetHashCode((int key1, string key2) obj)
    => HashCode.Combine(obj.key1, StringComparer.OrdinalIgnoreCase.GetHashCode(obj.key2));
}
 类似资料:
  • 我试图使字典的大小写不敏感。但是,我宣布它是一种财产,我怎么能让它变得不敏感呢。 我知道在定义时,我可以像这样使用它: 但是,我在接口和类中分别定义了它,比如 我怎么能让这个案子变得麻木不仁呢?

  • 问题内容: 我希望我的字典不区分大小写。 我有以下示例代码: 输出=练习更改颜色 我想要另一个字符串,(以大写字母开头)也给出相同的输出。 我相信有一种使用转换为小写字母的通用方法, 但是我不确定如何将其最好地集成到我的现有代码中。(如果无论如何这将是一种合理,简单的方法)。 问题答案: 如果我对您的理解正确,并且希望以一种不区分大小写的方式键入字典的键,则一种方法是将dict子类化并重载sett

  • 问题内容: 默认情况下,单词“ Word”和“ word”不相同。如何使Lucene不区分大小写? 问题答案: 最简单的方法是降低所有可搜索的内容以及查询的大小写。请参阅 文档。您也可以将查询用于不区分大小写的搜索,因为它绕过了。 如果需要,您可以将内容存储在不同的字段中以捕获不同的案例配置。

  • 问题内容: 如何更改strpos以使其不区分大小写。原因是如果的名称是 MadBike ,而搜索字词是 bike ,则该链接不会向我显示。我主要关心的是代码的速度。 问题答案: 您正在寻找 如果您无法使用该功能,则只需先调用两个字符串即可。 编辑 : 如果要查找带有变音符号的子字符串,将无法正常工作。 例如: 返回,但应该返回。

  • 考虑: 我试图在每边只显示100个字符,中间是搜索字符串。 这段代码实际上可以工作,但它是区分大小写的。如何使其不区分大小写?