我所拥有的是两个文件,sourcecolumns.txt
和destcolumns.txt
。我需要做的是将源与dest进行比较,如果dest不包含源值,则将其写入新文件。下面的代码有效,除了我有这样的区分大小写的问题:
因为有大写字母而不匹配,所以输出不正确。随时欢迎任何帮助!
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);
}
}
答案 0 :(得分:5)
您可以使用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 ) );
}
}
然后改变
if (destlinestotal.Contains( sline ))
到
if (destlinestotal.Contains( sline, StringComparison.OrdinalIgnoreCase ))
但是,如果这些集合很大并且/或者您经常这样做,那么您的处理方式效率非常低。基本上,您正在执行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);
}
}
回想起来,我实际上更喜欢这个解决方案而不是简单地为IEnumerable<string>
编写自己的不区分大小写的包含,除非您需要其他方法。实际上,使用HashSet实现维护的代码(您自己的代码)更少。
答案 1 :(得分:4)
为您的包含使用扩展方法。找到了一个很好的例子here on stack overflow Code不是我的,但我会在下面发布。
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
return source.IndexOf(toCheck, comp) >= 0;
}
string title = "STRING";
bool contains = title.Contains("string", StringComparison.OrdinalIgnoreCase);
答案 2 :(得分:0)
如果您不需要区分大小写,请在比较前使用string.ToUpper
将行转换为大写。