什么是"现代"的方式来找到两个列表<T>对象中的常见项目?

ind*_*dra 10 c# linq linq-to-objects generic-list

我有一个包含两个不同类型泛型列表,例如着想,让他们打电话ProductsEmployees.我正在尝试找到与员工位于同一位置的产品,即在哪里product.SiteId == emp.SiteId

List<Product> lstProds;
List<Employees> lstEmps;
Run Code Online (Sandbox Code Playgroud)

我的(老skool)大脑告诉我使用forEach循环找到匹配但我怀疑有一个('更好'/更快/更快?)的方式来使用Linq.任何人都可以照亮我吗?我在网上找到的所有例子都涉及原语列表(字符串/整数),并没有特别有用.

Jon*_*eet 17

我会说:

var products = from product in lstProds
               join employee in lstEmps on product.SiteId equals employee.SiteId
               select product;
Run Code Online (Sandbox Code Playgroud)

但是,如果有多个员工具有相同的站点ID,您将多次获得产品.您可以使用它Distinct来修复此问题,或构建一组站点ID:

var siteIds = new HashSet<int>(lstEmps.Select(emp => emp.SiteId));

var products = lstProds.Where(product => siteIds.Contains(product.SiteId));
Run Code Online (Sandbox Code Playgroud)

假设SiteIdint- 如果它是匿名类型或类似的东西,您可能需要一个额外的扩展方法:

public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source)
{
    return new HashSet<T>(source);
}
Run Code Online (Sandbox Code Playgroud)

然后:

var siteIds = lstEmps.Select(emp => emp.SiteId).ToHashSet();
var products = lstProds.Where(product => siteIds.Contains(product.SiteId));
Run Code Online (Sandbox Code Playgroud)

或者,如果您的员工很少,这将有效但速度相对较慢:

var products = lstProds.Where(p => lstEmps.Any(emp => p.SiteId == emp.SiteId));
Run Code Online (Sandbox Code Playgroud)

添加ToList对这些方法中的任何一个的调用来获取List<Product>而不是IEnumerable<Product>.