开发者

How to subtract one generic list from another in C#2.0

First of all, it very well could be that I'm approaching my problem the wrong way, in which case I'd gladly accept alternatives.

What I'm trying to achieve is to detect which drive was created after a USB device has been connected to a computer.

Here is the simplified workflow:

// 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 returns a list of strings of the removable drive letters. My idea was to get a list of removable drives before the device is connected, and another list after it is connected, and that by removing the contents of the first list from the second, I would be left with drives that were just connected (normally only one).

But I can't find a simple way of "subtracting" one list from another. Anyone could suggest a solution, or even a better way of achieving what I'm t开发者_运维百科rying to do.

Note: project is targeting the .NET framework 2.0, so no LINQ possible.

Thanks!


A general way to do this would be to add all the items from the source collection to a dictionary and then remove items in the other collection:

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;
}


For a small number of elements then a foreach loop with a Contains call should do the trick:

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);
}

If the collection has many elements then you could make the lookups more efficient by using a Dictionary<K,V> rather than a List<T>. (Ideally you'd use a HashSet<T>, but that's not available in version 2 of the framework.)


You can work with Linq extension method's Subtract and Insersect, same as you do with math set.

A = Original.

B = After.

A - (A Intersect B) = removed from original B - (A insersect B) = new

var intersect = A.Intersect(B);

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

Hope this works for you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜