2010-08-09 47 views
1

我有2个集:比较两个列表与LINQ的更好方法?

IEnumerable<Element> allElements 
List<ElementId> someElements, 

是什么做的简洁的方式一起如下:

[1]验证是否在someElements所有元素allElements存在,迅速返回时的条件失败。

[2]获得Element对象List<ElementId> someElements映射到的列表。

每个Element对象都有一个ElementId

谢谢。

回答

9

我这样做:

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

注意,如果在allElements任何重复的第一行会抛出异常。

+0

这是真棒解决方案,这清楚地表明,在使用LINQ人们仍然需要理解的复杂性和其他基本算法的东西。但对于小列表来说,它可能是一个开销。 – Andrey 2010-08-09 16:40:36

+1

如果有重复,MoreLinq的DistinctBy方法会派上用场:http://code.google.com/p/morelinq/source/browse/trunk/MoreLinq/DistinctBy.cs – tvanfosson 2010-08-09 17:24:55

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

效率不高的飞碟双向的答案,但对于合理大小的集合不够好:

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