2010-08-09 7 views
1

J'ai les 2 collections:Une meilleure façon de comparer deux listes avec LINQ?

IEnumerable<Element> allElements 
List<ElementId> someElements, 

Quelle est une façon concise de faire ce qui suit ensemble:

[1] Vérifier que tous les éléments de someElements existent dans allElements, revenir rapidement lorsque la condition échoue.

et

[2] Obtenir une liste des objets qui ElementList<ElementId> someElements cartes à.

Chaque objet a une ElementElementId

Merci.

Répondre

9

je ferais ceci:

var map = allElements.ToDictionary(x => x.Id);  
if (!someElements.All(id => map.ContainsKey(id)) 
{ 
    // Return early 
} 
var list = someElements.Select(x => map[x]) 
         .ToList(); 

Notez que la première ligne lancera une exception s'il y a des doublons dans allElements.

+0

c'est une solution impressionnante, cela montre clairement que tout en utilisant les LINQ ont encore besoin de comprendre la complexité et d'autres choses algorithmiques fondamentales . mais pour les petites listes, cela peut être une surcharge. – Andrey

+1

Dans le cas où il existe des doublons, votre méthode DistinctBy de MoreLinq serait utile: http://code.google.com/p/morelinq/source/browse/trunk/MoreLinq/DistinctBy.cs – tvanfosson

1
  1. someElements.All(e => allElements.Contains(e));
  2. allElements.Where(e => someElements.Contains(e.ElementId));
1

Pas aussi efficace que la réponse au pigeon d'argile, mais assez bon pour les collections de taille raisonnable:

IEnumerable<Element> allElements = new List<Element> 
    { new Element { Id = 1 }, new Element { Id = 2 } }; 
List<int> someElements = new List<int> { 1, 2 }; 

var query = 
    (from element in allElements 
    join id in someElements on element.Id equals id 
    select element) 
    .ToList(); 

if (query.Count != someElements.Count) 
{ 
    Console.WriteLine("Not all items found."); 
} 

foreach (var element in query) 
{ 
    Console.WriteLine ("Found: " + element.Id); 
} 
Questions connexes