4 c# string case-insensitive string-comparison
我有两个文件,sourcecolumns.txt和destcolumns.txt.我需要做的是将源与dest进行比较,如果dest不包含源值,则将其写入新文件.下面的代码有效,除了我有这样的区分大小写的问题:
来源:CPI
dest:Cpi
这些因为大写字母而不匹配,所以输出不正确.随时欢迎任何帮助!
string[] sourcelinestotal =
File.ReadAllLines("C:\\testdirectory\\" + "sourcecolumns.txt");
string[] destlinestotal =
File.ReadAllLines("C:\\testdirectory\\" + "destcolumns.txt");
foreach (string sline in sourcelinestotal)
{
if (destlinestotal.Contains(sline))
{
}
else
{
File.AppendAllText("C:\\testdirectory\\" + "missingcolumns.txt", sline);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用扩展方法执行此操作IEnumerable<string>:
public static class EnumerableExtensions
{
public static bool Contains( this IEnumerable<string> source, string value, StringComparison comparison )
{
if (source == null)
{
return false; // nothing is a member of the empty set
}
return source.Any( s => string.Equals( s, value, comparison ) );
}
}
Run Code Online (Sandbox Code Playgroud)
然后改变
if (destlinestotal.Contains( sline ))
Run Code Online (Sandbox Code Playgroud)
至
if (destlinestotal.Contains( sline, StringComparison.OrdinalIgnoreCase ))
Run Code Online (Sandbox Code Playgroud)
但是,如果这些集合很大并且/或者您经常这样做,那么您的处理方式效率非常低.从本质上讲,您正在进行O(n 2)操作 - 对于源中的每一行,您可以将其与目标中的所有行进行比较.最好使用case insenstivie比较器从目标列创建HashSet,然后遍历源列,检查每个列是否存在于目标列的HashSet中.这将是一个O(n)算法.请注意,HashSet上的Contains将使用您在构造函数中提供的比较器.
string[] sourcelinestotal =
File.ReadAllLines("C:\\testdirectory\\" + "sourcecolumns.txt");
HashSet<string> destlinestotal =
new HashSet<string>(
File.ReadAllLines("C:\\testdirectory\\" + "destcolumns.txt"),
StringComparer.OrdinalIgnoreCase
);
foreach (string sline in sourcelinestotal)
{
if (!destlinestotal.Contains(sline))
{
File.AppendAllText("C:\\testdirectory\\" + "missingcolumns.txt", sline);
}
}
Run Code Online (Sandbox Code Playgroud)
回想起来,我实际上更喜欢这个解决方案而不是简单地编写自己的不区分大小写包含,IEnumerable<string>除非你需要其他方法.实际上,通过使用HashSet实现来维护的代码(您自己的代码)更少.