2012-05-22 2 views
2

У меня есть два хэшета, которые загружают данные из двух разных текстовых файлов. Содержимое обоих текстовых файлов выглядит следующим образом:Сравнение двух хэш-наборов

name/12441431252132 
name1/323244231244142 
name2/32423452524234 

Мой код в настоящее время загрузки оба файла и убедитесь, что у меня есть только уникальные результаты textFile2:

HashSet<string> txt1 = new HashSet<string>(File.ReadLines("textFile1.txt")); 
HashSet<string> txt2 = new HashSet<string>(File.ReadLines("textFile2.txt")); 

txt2.ExceptWith(txt1); 

Моя проблема в том, что она только удаляет линии, основанные на критериях, если вся строка соответствует. Я хочу удалить его на основе базы имен. Например, name2 никогда не следует включать, если его в textFile1, даже если идентификатор после/отличается.

Как бы это осуществить?

Дайте мне знать, если мои объяснения не будут хорошими, я постараюсь улучшить его - и, пожалуйста, извините мой английский!

+0

Являются ли имена в каждом текстовом файле уникальными? – spender

+0

Не всегда может быть больше одного из них в текстовом файле1, но если они не должны быть включены после ExceptWith в txt2 – hariette

ответ

3

Вы можете просто добавить строку расщеплению на отдельные имена и остальной контент - этот подход является немного «грязным», так что в реальном коде я бы, вероятно, использовать цикл просмотра и внедрить специализированные классы:

var content = File.ReadLines("textFile1.txt").Select(line => 
{ 
    var parts = line.Split('/'); 
    return new 
    { 
     Name = parts[0], 
     Content = parts[1] 
    }; 
}); 

HashSet<string> names = new HashSet<string>(content.Select(c=> c.Name)); 
HashSet<string> txt2 = new HashSet<string>(File.ReadLines("textFile2.txt")); 
var uniques = txt2.Where(line => !names.Contains(line.Split('/')[0])); 
+0

Как получить первое уникальное имя и идентификатор из uniques var? позже в коде мне нужно использовать первые и сделать их в строки – hariette

+0

@hariette: Мне было непонятно, что вы хотели бы выделить строки в парах Name/Value для 'txt2', а также - в этом case использует тот же подход, что и для разбора 'content' – BrokenGlass

0

, если вы разделите на /, вы можете создать HashSet имен, которые появляются в первом наборе, а затем выбрать элементы во втором наборе, которые имеют имя, которое не отображается в первом наборе.

var nameValues1= 
    File 
    .ReadLines(fileName) 
    .Select(line=>line.Split('/')) 
    .Select(parts=>new {name=parts[0],value=parts[1]}); 
var nameValues2= 
    File 
    .ReadLines(fileName2) 
    .Select(line=>line.Split('/')) 
    .Select(parts=>new {name=parts[0],value=parts[1]}); 
var names1=new HashSet<string>(nameValues1.Select(nv=>nv.name); 
var result= 
    nameValues2 
    .Where(nv=>!names1.Contains(nv.name)) 
    .Select(nv=>string.Format("{0}/{1}",nv.name,nv.value); 
0

Вы уверены, что HashSet по-прежнему лучший выбор? Здесь используется другой подход с использованием :

var lines1 = System.IO.File.ReadLines(path1); 
var lines2 = System.IO.File.ReadLines(path2); 
var allItems = new Dictionary<String, String>(); 
foreach (var line in lines1.Concat(lines2)) 
{ 
    String[] tokens = line.Split('/'); 
    if (tokens.Length == 2) 
    { 
     String name = tokens[0]; 
     String number = tokens[1]; 
     if (!allItems.ContainsKey(name)) 
      allItems.Add(name, number); 
    } 
} 
+0

Это проблематично, поскольку OP утверждает, что имена в файле ** не являются ** уникальными. – spender

+0

@spender: Но его требование - отфильтровать дубликаты имен. Вышеуказанный подход мог бы переопределить существующие номера имен, но их можно было легко изменить, чтобы сделать что-то еще. –

+1

@spender: Поскольку OP просто хочет взять первый, я отредактировал выше, чтобы проверить существование с помощью 'ContainsKey'. –