4

我有两个文件,sourcecolumns.txtdestcolumns.txt. 我需要做的是将 source 与 dest 进行比较,如果 dest 不包含源值,请将其写入新文件。下面的代码有效,除了我有这样的区分大小写的问题:

来源:CPI
目的地: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);
    }
}
4

3 回答 3

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 ) 操作——对于源中的每一行,您可能会将其与目标中的所有行进行比较。最好使用不区分大小写的比较器从目标列创建一个 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); 
    } 
}

回想起来,我实际上更喜欢这个解决方案,而不是简单地编写自己的不区分大小写的 contains for,IEnumerable<string>除非您需要其他方法。通过使用 HashSet 实现,实际上需要维护的(您自己的)代码更少。

于 2010-04-28T18:09:31.313 回答
4

为您的包含使用扩展方法。在这里找到了一个关于堆栈溢出的精彩示例代码不是我的,但我会在下面发布。

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);
于 2010-04-28T17:58:21.157 回答
0

如果您不需要区分大小写,请string.ToUpper在比较之前将行转换为大写。

于 2010-04-28T17:55:42.357 回答