2010-02-15 3 views
5

Tout d'abord, il se pourrait très bien que j'aborde mon problème de la mauvaise manière, auquel cas j'accepterais volontiers des alternatives. Ce que j'essaie de réaliser est de détecter quel lecteur a été créé après la connexion d'un périphérique USB à un ordinateur.Comment soustraire une liste générique d'une autre en C# 2.0

Voici le flux de travail simplifié:

// 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 retourne une liste de chaînes des lettres de lecteur amovible. Mon idée était d'obtenir une liste de lecteurs amovibles avant l'appareil est connecté, et une autre liste après il est connecté, et qu'en enlevant le contenu de la première liste de la seconde, je serais parti avec des lecteurs qui étaient juste connectés (normalement un seul).

Mais je ne trouve pas un moyen simple de "soustraire" une liste d'une autre. Tout le monde pourrait suggérer une solution, ou même un meilleur moyen de réaliser ce que j'essaie de faire.

Remarque: le projet cible le .NET Framework 2.0, donc aucun LINQ possible.

Merci!

Répondre

1

Pour un petit nombre d'éléments puis une boucle foreach avec un appel Contains devrait faire l'affaire:

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

Si la collection comporte de nombreux éléments, vous pouvez faire des recherches plus efficace en utilisant un Dictionary<K,V> plutôt que un List<T>. (Idéalement, vous utiliseriez un HashSet<T>, mais ce n'est pas disponible dans la version 2 du framework.)

+0

J'ai choisi cette réponse parce que j'avais besoin d'une chose unique. Si j'avais eu besoin de le faire à plusieurs reprises et à différents endroits, j'aurais probablement mis en œuvre le soustraction de la réponse de Lee. – Fueled

3

Une façon générale de procéder consiste à ajouter tous les éléments de la collection source dans un dictionnaire, puis à supprimer les éléments dans l'autre 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; 
} 
+0

Une solution efficace, mais la méthode est mal nommée. Il ne retourne pas l'intersection des deux séquences. – LukeH

+0

Dans mon esprit les deux réponses sont valides, mais à cause de mon exigence, j'ai choisi la voie facile. – Fueled

1

vous pouvez travailler avec Soustraire et Insersect de méthode d'extension LINQ, comme vous le faites avec jeu de mathématiques.

A = Original.

B = Après.

A - (A Intersection B) = retiré de l'original B - (A insersect B) = nouveau

var coupent = A.Intersect (B);

var enlevé = A.Sous-fond (intersection); var nouveau = B.Sous-trait (intersection)

Espérons que cela fonctionne pour vous.

+3

Linq n'a pas de méthode appelée Subtract (ou Substract). Je pense que vous voulez dire ['Except'] (http://msdn.microsoft.com/en-us/library/bb300779.aspx). – JLRishe

Questions connexes