简体   繁体   English

在不区分大小写的HashSet <string>中获取值

[英]Get value in case-insensitive HashSet<string>

I have case-insensitive HashSet<string> : 我有不区分大小写的HashSet<string>

private HashSet<string> a = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);

I'm curious if I can now extract the string in the actual case. 我很好奇,如果我现在可以在实际情况下提取字符串。 Pseudo code of what I need: 我需要的伪代码:

return a.Contains(word) ? a[word] : null;

(just a pseudo code, it won't work) (只是一个伪代码,它不会工作)

For example, I have string " TestXxX " in the HashSet. 例如,我在HashSet中有字符串“ TestXxX ”。 I need for the code which gets "testxxx" (or "tEsTXXx") as input and returns " TestXxX ". 我需要将“testxxx”(或“tEsTXXx”)作为输入并返回“ TestXxX ”的代码。

My current workaround is to use Dictionary<string,string> instead and put the same value for both key and value. 我目前的解决方法是使用Dictionary<string,string>并为key和value添加相同的值。 This is obviously not elegant and consumes 2x memory as it actually needs. 这显然不优雅,并且实际需要消耗2倍的内存。

You can override KeyedCollection 您可以覆盖KeyedCollection

public class Keyed : KeyedCollection<string, string>
{
    public Keyed(IEqualityComparer<string> comparer) : base(comparer)
    {

    }

    protected override string GetKeyForItem(string item)
    {
        return item;
    }
}

Then use it: 然后使用它:

var keyed = new Keyed(StringComparer.InvariantCultureIgnoreCase);
keyed.Add("TestXxX");

Console.WriteLine(keyed["tEsTXXx"]);

HashSet<T> doesn't expose any functionality to achieve what you're looking for. HashSet<T>不会公开任何功能来实现您所需的功能。 If you don't need to use a HashSet , then Kirill Polishchuk's answer makes sense to me. 如果您不需要使用HashSet ,那么Kirill Polishchuk的回答对我来说很有意义。

Otherwise, if you do need a HashSet , a somewhat nasty hack is to use a custom equality comparer. 否则,如果你确实需要一个HashSet ,一个有点讨厌的黑客是使用自定义相等比较器。 Create your own equality comparer that simply forwards all requests to StringComparer.InvariantCultureIgnoreCase , but caches the last-passed objects. 创建自己的相等比较器,只是将所有请求转发给StringComparer.InvariantCultureIgnoreCase ,但缓存最后传递的对象。

If you have that, then after a.Contains(word) returns true , the last-passed objects should be 1) word and 2) the word as it appears in a . 如果你有,那么在a.Contains(word)返回true ,最后传递的对象应该是1) word和2)它出现在a的单词。

Strictly speaking, this is not guaranteed to work, since HashSet is allowed to call the comparer with different values than what you expect. 严格地说,这不能保证可以工作,因为允许HashSet使用与您期望的值不同的值来调用比较器。 It's certain to work in current versions of .NET Framework though and unlikely to break in the future: the comparer equality function obviously needs to be called with those arguments in order for Contains to return the correct value, and there is no reason why it would be called with any other arguments except to intentionally break code like this. 它确实可以在当前版本的.NET Framework中工作,但不太可能在将来中断:比较器相等功能显然需要使用这些参数调用,以便Contains返回正确的值,并且没有理由为什么它会可以使用任何其他参数调用,除非故意破坏这样的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM