2010-02-15 5 views
5

Прежде всего, это может быть так, что я неправильно подхожу к своей проблеме, и в этом случае я с радостью принимаю альтернативы.Как вычесть один общий список из другого в C# 2.0

Я пытаюсь определить, какой диск был создан после подключения USB-устройства к компьютеру.

Вот упрощенный рабочий процесс:

// Get list of removable drives before user connects the USB cable 
List<string> listRemovableDrivesBefore = GetRemovableDriveList(); 

// Tell user to connect USB cable 
... 

// Start listening for a connection of a USB device 
... 

// Loop until device is connected or time runs out 
do 
{ 
    ... 
} while 

// Get list of removable drives after USB device is connected 
List<string> listRemovableDrivesAfter = GetRemovableDriveList(); 

// Find out which drive was created after USB has been connected 
??? 

GetRemovableDriveList возвращает список строк букв съемных дисков. Моя идея состояла в том, чтобы получить список съемных дисков до, устройство подключено, а еще один список после связан и что, удалив содержимое первого списка со второго, я останусь с дисками, которые были просто связаны (обычно только один).

Но я не могу найти простой способ «вычитать» один список из другого. Любой может предложить решение или даже лучший способ добиться того, что я пытаюсь сделать.

Примечание: проект нацелен на .NET framework 2.0, поэтому LINQ не возможно.

Спасибо!

ответ

1

Для небольшого числа элементов, то А foreach петли с Contains вызова должен сделать трюк:

List<string> listRemovableDrivesBefore = GetRemovableDriveList(); 
// ... 
List<string> listRemovableDrivesAfter = GetRemovableDriveList(); 

List<string> addedDrives = new List<string>(); 
foreach (string s in listRemovableDrivesAfter) 
{ 
    if (!listRemovableDrivesBefore.Contains(s)) 
     addedDrives.Add(s); 
} 

Если коллекция имеет много элементов, то вы можете сделать поиски более эффективным использованием Dictionary<K,V>, а не a List<T>. (В идеале вы бы использовали HashSet<T>, но это не доступно в версии 2 фреймворка.)

+0

Я выбрал этот ответ, потому что мне нужна была единовременная вещь. Если бы мне пришлось делать это неоднократно и в разных местах, я бы, вероятно, выполнил вычитание из ответа Ли. – Fueled

3

Общий способ сделать это - добавить все элементы из исходной коллекции в словарь и затем удалить элементы в другая коллекция:

public static IEnumerable<T> Subtract<T>(IEnumerable<T> source, IEnumerable<T> other) 
{ 
    return Subtract(source, other, EqualityComparer<T>.Default); 
} 

public static IEnumerable<T> Subtract<T>(IEnumerable<T> source, IEnumerable<T> other, IEqualityComparer<T> comp) 
{ 
    Dictionary<T, object> dict = new Dictionary<T, object>(comp); 
    foreach(T item in source) 
    { 
     dict[item] = null; 
    } 

    foreach(T item in other) 
    { 
     dict.Remove(item); 
    } 

    return dict.Keys; 
} 
+0

Эффективное решение, но метод неверно назван. Он не возвращает пересечение двух последовательностей. – LukeH

+0

На мой взгляд, оба ответа действительны, но из-за моего требования я выбрал простой способ. – Fueled

1

вы можете работать с Linq метод расширения в Вычесть и Insersect, так же, как и вы с математикой набора.

A = Оригинал.

B = После.

А - (А Интерсект В) = удалены из первоначального В - (А insersect B) = новый

вар пересекаются = A.Intersect (В);

var removed = A.Substract (intersect); var new = B.Substract (intersect)

Надеюсь, это сработает для вас.

+3

У Linq нет метода под названием Subtract (или Substract). Я думаю, вы имеете в виду ['Except'] (http://msdn.microsoft.com/en-us/library/bb300779.aspx). – JLRishe