C # соответствует двум текстовым файлам, чувствительна к регистру - PullRequest
4 голосов
/ 28 апреля 2010

У меня есть два файла, sourcecolumns.txt и destcolumns.txt. Что мне нужно сделать, это сравнить источник с dest, и если dest не содержит значения источника, запишите его в новый файл. Приведенный ниже код работает, за исключением тех случаев, когда у меня возникают проблемы, чувствительные к регистру, например:

источник: ИПЦ
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);
    }
}

Ответы [ 3 ]

5 голосов
/ 28 апреля 2010

Вы можете сделать это, используя метод расширения для 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). обратите внимание, что Contains в HashSet будет использовать компаратор, предоставленный вами в конструкторе.

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.

4 голосов
/ 28 апреля 2010

Используйте метод расширения для вашего Contains. Здесь был найден блестящий пример переполнения стека Код не мой, но я опубликую его ниже.

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);
0 голосов
/ 28 апреля 2010

Если вам не нужна чувствительность к регистру, преобразуйте строки в верхний регистр, используя string.ToUpper перед сравнением.

...