我有HashSet参数的方法.我需要在其中做不区分大小写的包含:
public void DoSomething(HashSet<string> set, string item)
{
var x = set.Contains(item);
...
}
Run Code Online (Sandbox Code Playgroud)
是否可以使现有的HashSet不区分大小写(不创建新的)?
我正在寻找具有最佳性能的解决方案.
编辑
包含可以多次调用.因此,由于性能低于本机HashSet Contains方法,IEnumerable扩展对我来说是不可接受的.
解
既然,回答我的问题是NO,那是不可能的,我已经创建并使用了以下方法:
public HashSet<string> EnsureCaseInsensitive(HashSet<string> set)
{
return set.Comparer == StringComparer.OrdinalIgnoreCase
? set
: new HashSet<string>(set, StringComparer.OrdinalIgnoreCase);
}
Run Code Online (Sandbox Code Playgroud)
Tim*_*lds 109
该HashSet<T>构造具有过载,可以让你在一个自定义的传递IEqualityComparer<string>.在静态StringComparer类中已经为您定义了一些这些,其中一些忽略了大小写.例如:
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
set.Add("john");
Debug.Assert(set.Contains("JohN"));
Run Code Online (Sandbox Code Playgroud)
你必须在构建时做出这个改变HashSet<T>.一旦存在,您就无法更改IEqualityComparer<T>它的使用.
只要你知道,在默认情况下(如果你不以任何传递IEqualityComparer<T>到HashSet<T>构造函数),它使用EqualityComparer<T>.Default来代替.
在我发布答案后,问题似乎已经改变了.如果你必须做的情况下,不区分大小写在现有的情况下,搜索敏感 HashSet<string>,你将不得不做线性搜索:
set.Any(s => string.Equals(s, item, StringComparison.OrdinalIgnoreCase));
Run Code Online (Sandbox Code Playgroud)
没有办法解决这个问题.
你不能神奇地使区分大小写的HashSet(或Dictionary)以不区分大小写的方式运行.
如果您不能依赖传入HashSet不区分大小写,则必须在函数内重新创建一个.
最紧凑的代码 - 使用现有集合中的构造函数:
var insensitive = new HashSet<string>(
set, StringComparer.InvariantCultureIgnoreCase);
Run Code Online (Sandbox Code Playgroud)
请注意,复制HashSet与遍历所有项目一样昂贵,因此如果您的函数仅在搜索时执行,则迭代所有项目会更便宜(O(n)).如果您的函数多次调用以进行单个不区分大小写的搜索,则应尝试将其正确传递HashSet给它.
| 归档时间: |
|
| 查看次数: |
22980 次 |
| 最近记录: |