2010-02-15 11 views
5

Zunächst könnte es sehr gut sein, dass ich mein Problem auf die falsche Weise anspreche, in diesem Fall würde ich gerne Alternativen akzeptieren.Wie man eine generische Liste von einer anderen in C# 2.0 subtrahiert

Was ich versuche zu erreichen, ist festzustellen, welches Laufwerk erstellt wurde, nachdem ein USB-Gerät an einen Computer angeschlossen wurde. Hier

ist die vereinfachte 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 gibt eine Liste von Strings der abnehmbaren Laufwerksbuchstaben. Meine Idee war, eine Liste von Wechseldatenträgern vor das Gerät ist verbunden, und eine andere Liste nach ist es verbunden, und dass durch Entfernen der Inhalt der ersten Liste von der zweiten, würde ich mit Laufwerken bleiben waren nur verbunden (normalerweise nur einer).

Aber ich finde keine einfache Möglichkeit, eine Liste von einer anderen zu "subtrahieren". Jeder könnte eine Lösung oder sogar einen besseren Weg vorschlagen, um das zu erreichen, was ich versuche.

Hinweis: Projekt zielt auf das .NET Framework 2.0, also keine LINQ möglich.

Danke!

Antwort

1

Für eine kleine Anzahl von Elementen dann eine foreach Schleife mit einem Contains Aufruf den Trick tun sollten:

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

Wenn die Sammlung viele Elemente hat, dann könnten Sie die Lookups machen effizienter durch eine Dictionary<K,V> mit nicht a List<T>. (Idealerweise würden Sie HashSet<T> verwenden, aber das ist in Version 2 des Frameworks nicht verfügbar.)

+0

Ich wählte diese Antwort, weil ich eine einmalige Sache brauchte. Wenn ich das wiederholt und an verschiedenen Stellen hätte machen müssen, hätte ich wahrscheinlich den Subtract von Lees Antwort implementiert. – Fueled

3

Eine allgemeine Möglichkeit besteht darin, alle Elemente aus der Quellensammlung einem Wörterbuch hinzuzufügen und Elemente darin zu entfernen die andere Sammlung:

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

Eine effiziente Lösung, aber die Methode ist falsch benannt. Es gibt den Schnittpunkt der beiden Sequenzen nicht zurück. – LukeH

+0

In meiner Meinung sind beide Antworten gültig, aber aufgrund meiner Anforderung wählte ich den einfachen Weg. – Fueled

1

können Sie arbeiten mit Linq subtrahieren und Insersect des Erweiterungsmethode, genau wie Sie mit Mathe-Set tun.

A = Original.

B = Nach.

A - (A Intersect B) von den ursprünglich entfernt = B - (A insersect B) = neu

var schneiden = A.Intersect (B);

var removed = A.Zusammenfassung (Schnittpunkt); var new = B.Substract (schneiden)

Hoffe, das funktioniert für Sie.

+3

Linq hat keine Methode namens Subtract (oder Substract). Ich denke du meinst ['Außer '] (http://msdn.microsoft.com/en-us/library/bb300779.aspx). – JLRishe