我确信有一种很好的方法可以做到这一点(我猜测其中一种扩展方法?),但我很难在Google上找到它。
基本上我有一个自定义类列表;我想从中选择一些项目到一个新的List中,其中一个属性等于另一个List中的任何值。
这是我正在尝试做的一个(简化)快速示例:
public class Job
{
public int Number;
public string ClientCompanyName;
}
List<Job> lstJobs = new List<Job>();
List<Job> lstCompare = new List<Job>();
通常我会做类似的事情:
List<Job> lstFiltered = new List<Job>();
foreach(Job jobThis in lstCompare)
{
foreach(jobComp in lstCompare)
{
if(jobThis.Number = jobComp.Number)
{
lstFiltered.Add(jobThis);
}
}
}
是否有一种扩展方法可以将最后一位加入(理想情况下)一行?
干杯
答案 0 :(得分:8)
您可以使用Intersect()
:
答案 1 :(得分:2)
使用Intersect
。
要使其与您的自定义比较一起使用,您需要在类中实现IEquatable<T>
或为类创建一个新类IEqualityComparer<T>
并将其传递给Intersect
的重载。< / p>
答案 2 :(得分:2)
Jez的,
您可以使用LINQ intersect
功能,或尝试:
var matches = from jobs in lstJobs
join comp in lstCompare on jobs.Number equals comp.Number
select jobs;
或LINQ语法:
var matches = lstJobs.Join(lstCompare, jobs => jobs.Number,
comp => comp.Number, (jobs, comp) => jobs);
这里是基于原始循环的reSharper版本:
List<Job> lstFiltered = (lstJobs.SelectMany(jobThis => lstCompare,
(jobThis, jobComp) => new {jobThis, jobComp})
.Where(@t => @t.jobThis.Number == @t.jobComp.Number)
.Select(@t => @t.jobThis)).ToList();
略显冗长,但另一种方法是给猫皮肤。
设置为新列表的[已编辑] ,而不是选定的元素 - doh
答案 3 :(得分:1)
var lstFiltered = lstJobs
.Where(job => lstCompare.Any(item => item.Number == job.Number))
.ToList();
如果lstCompare
中的项目数量很少,则上述解决方案效果很好。对于更大的比较列表,您可能希望使用一些基于散列的集合。
var compareSet = new HashSet<int>(lstCompare.Select(item => item.Number));
var lstFiltered = lstJobs
.Where(job => compareSet.Contains(job.Number))
.ToList();
如果比较条件更复杂或者在多个地方需要,则应创建一个实现IEqualityComparer<T>
的比较器类。然后你可以像其他人已经建议的那样使用Intersect()
方法。但是,它在功能上与上述解决方案不同。当我的解决方案返回所有匹配元素时,它只返回不同的元素在某些应用中,这可能是一个显着的差异。
如果需要,可以轻松更改我的第二个示例以使用IEqualityComparer<T>
。 HashSet<T>
将比较器作为第二个参数。