【问题标题】:Get value in case-insensitive HashSet<string>在不区分大小写的 HashSet<string> 中获取值
【发布时间】:2015-08-16 22:57:00
【问题描述】:

我有不区分大小写的HashSet&lt;string&gt;:

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

我很好奇现在是否可以在实际情况下提取字符串。我需要的伪代码:

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

(只是一个伪代码,它不会工作)

例如,我在 HashSet 中有字符串“TestXxX”。我需要将“testxxx”(或“tEsTXXx”)作为输入并返回“TestXxX”的代码。

我当前的解决方法是改用Dictionary&lt;string,string&gt; 并为键和值输入相同的值。这显然不优雅,并且消耗了实际需要的 2 倍内存。

【问题讨论】:

  • 集合通常不包含索引。你要么必须切换到List&lt;T&gt;,要么创建一个派生自KeyedCollection&lt;T, T&gt;的强类型类
  • 如果您不再需要该集合,您可以IntersectWith(new [] { word }) 并迭代结果,我想。但这显然不是一个通用的解决方案:克隆套装只是为了获得一件物品是不必要的工作。

标签: c# .net hashtable


【解决方案1】:

您可以覆盖KeyedCollection

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

    }

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

然后使用它:

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

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

【讨论】:

    【解决方案2】:

    HashSet&lt;T&gt; 不公开任何功能来实现您正在寻找的东西。如果您不需要使用 HashSet,那么 Kirill Polishchuk 的回答对我来说很有意义。

    否则,如果您确实需要 HashSet,那么使用自定义相等比较器是一个有点讨厌的技巧。创建您自己的相等比较器,它只是将所有请求转发到StringComparer.InvariantCultureIgnoreCase,但会缓存最后传递的对象。

    如果有,那么在a.Contains(word) 返回true 之后,最后传递的对象应该是 1) word 和 2) a 中出现的单词。

    严格来说,这并不能保证有效,因为HashSet 可以使用与您预期不同的值调用比较器。虽然它肯定可以在当前版本的 .NET Framework 中工作,但未来不太可能中断:显然需要使用这些参数调用比较器相等函数,以便 Contains 返回正确的值,并且没有理由为什么除了故意破坏这样的代码之外,它将使用任何其他参数调用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-09
      • 2012-02-03
      • 2013-08-05
      • 1970-01-01
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      相关资源
      最近更新 更多